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