Chris@16
|
1 /*=============================================================================
|
Chris@16
|
2 Copyright (c) 2001-2011 Joel de Guzman
|
Chris@16
|
3 Copyright (c) 2006 Dan Marsden
|
Chris@16
|
4
|
Chris@16
|
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
7 ==============================================================================*/
|
Chris@16
|
8 #if !defined(FUSION_STRICTEST_TRAVERSAL_20060123_2101)
|
Chris@16
|
9 #define FUSION_STRICTEST_TRAVERSAL_20060123_2101
|
Chris@16
|
10
|
Chris@101
|
11 #include <boost/fusion/support/config.hpp>
|
Chris@16
|
12 #include <boost/config.hpp>
|
Chris@16
|
13 #include <boost/mpl/or.hpp>
|
Chris@16
|
14 #include <boost/mpl/if.hpp>
|
Chris@16
|
15 #include <boost/fusion/support/category_of.hpp>
|
Chris@16
|
16 #include <boost/fusion/mpl.hpp>
|
Chris@16
|
17 #include <boost/fusion/algorithm/iteration/fold.hpp>
|
Chris@16
|
18 #include <boost/type_traits/remove_reference.hpp>
|
Chris@16
|
19 #include <boost/type_traits/is_convertible.hpp>
|
Chris@16
|
20
|
Chris@16
|
21 namespace boost { namespace fusion
|
Chris@16
|
22 {
|
Chris@16
|
23 struct forward_traversal_tag;
|
Chris@16
|
24 struct bidirectional_traversal_tag;
|
Chris@16
|
25 struct random_access_traversal_tag;
|
Chris@16
|
26
|
Chris@16
|
27 namespace detail
|
Chris@16
|
28 {
|
Chris@16
|
29 template<typename Tag1, typename Tag2,
|
Chris@16
|
30 bool Tag1Stricter = boost::is_convertible<Tag2,Tag1>::value>
|
Chris@16
|
31 struct stricter_traversal
|
Chris@16
|
32 {
|
Chris@16
|
33 typedef Tag1 type;
|
Chris@16
|
34 };
|
Chris@16
|
35
|
Chris@16
|
36 template<typename Tag1, typename Tag2>
|
Chris@16
|
37 struct stricter_traversal<Tag1,Tag2,false>
|
Chris@16
|
38 {
|
Chris@16
|
39 typedef Tag2 type;
|
Chris@16
|
40 };
|
Chris@16
|
41
|
Chris@16
|
42 struct strictest_traversal_impl
|
Chris@16
|
43 {
|
Chris@16
|
44 template<typename Sig>
|
Chris@16
|
45 struct result;
|
Chris@16
|
46
|
Chris@16
|
47 template<typename StrictestSoFar, typename Next>
|
Chris@16
|
48 struct result<strictest_traversal_impl(StrictestSoFar, Next)>
|
Chris@16
|
49 {
|
Chris@16
|
50 typedef typename remove_reference<Next>::type next_value;
|
Chris@16
|
51 typedef typename remove_reference<StrictestSoFar>::type strictest_so_far;
|
Chris@16
|
52
|
Chris@16
|
53 typedef strictest_so_far tag1;
|
Chris@16
|
54 typedef typename traits::category_of<next_value>::type tag2;
|
Chris@16
|
55
|
Chris@16
|
56 typedef typename stricter_traversal<tag1,tag2>::type type;
|
Chris@16
|
57 };
|
Chris@16
|
58
|
Chris@16
|
59 // never called, but needed for decltype-based result_of (C++0x)
|
Chris@16
|
60 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
61 template<typename StrictestSoFar, typename Next>
|
Chris@101
|
62 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
Chris@16
|
63 typename result<strictest_traversal_impl(StrictestSoFar, Next)>::type
|
Chris@16
|
64 operator()(StrictestSoFar&&, Next&&) const;
|
Chris@16
|
65 #endif
|
Chris@16
|
66 };
|
Chris@16
|
67
|
Chris@16
|
68 template<typename Sequence>
|
Chris@16
|
69 struct strictest_traversal
|
Chris@16
|
70 : result_of::fold<
|
Chris@16
|
71 Sequence, fusion::random_access_traversal_tag,
|
Chris@16
|
72 strictest_traversal_impl>
|
Chris@16
|
73 {};
|
Chris@16
|
74
|
Chris@16
|
75 }
|
Chris@16
|
76 }}
|
Chris@16
|
77
|
Chris@16
|
78 #endif
|