1 2 #ifndef BOOST_MPL_AUX_BEGIN_END_IMPL_HPP_INCLUDED 3 #define BOOST_MPL_AUX_BEGIN_END_IMPL_HPP_INCLUDED 4 5 // Copyright Aleksey Gurtovoy 2000-2004 6 // 7 // Distributed under the Boost Software License, Version 1.0. 8 // (See accompanying file LICENSE_1_0.txt or copy at 9 // http://www.boost.org/LICENSE_1_0.txt) 10 // 11 // See http://www.boost.org/libs/mpl for documentation. 12 13 // $Id: begin_end_impl.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ 14 // $Date: 2008-10-10 23:19:02 -0700 (Fri, 10 Oct 2008) $ 15 // $Revision: 49267 $ 16 17 #include <boost/mpl/begin_end_fwd.hpp> 18 #include <boost/mpl/sequence_tag_fwd.hpp> 19 #include <boost/mpl/void.hpp> 20 #include <boost/mpl/eval_if.hpp> 21 #include <boost/mpl/aux_/has_begin.hpp> 22 #include <boost/mpl/aux_/na.hpp> 23 #include <boost/mpl/aux_/traits_lambda_spec.hpp> 24 #include <boost/mpl/aux_/config/eti.hpp> 25 26 namespace boost { namespace mpl { 27 28 29 namespace aux { 30 31 template< typename Sequence > 32 struct begin_type 33 { 34 typedef typename Sequence::begin type; 35 }; 36 template< typename Sequence > 37 struct end_type 38 { 39 typedef typename Sequence::end type; 40 }; 41 42 } 43 44 // default implementation; conrete sequences might override it by 45 // specializing either the 'begin_impl/end_impl' or the primary 46 // 'begin/end' templates 47 48 template< typename Tag > 49 struct begin_impl 50 { 51 template< typename Sequence > struct apply 52 { 53 typedef typename eval_if<aux::has_begin<Sequence, true_>, 54 aux::begin_type<Sequence>, void_>::type type; 55 }; 56 }; 57 58 template< typename Tag > 59 struct end_impl 60 { 61 template< typename Sequence > struct apply 62 { 63 typedef typename eval_if<aux::has_begin<Sequence, true_>, 64 aux::end_type<Sequence>, void_>::type type; 65 }; 66 }; 67 68 // specialize 'begin_trait/end_trait' for two pre-defined tags 69 70 # define AUX778076_IMPL_SPEC(name, tag, result) \ 71 template<> \ 72 struct name##_impl<tag> \ 73 { \ 74 template< typename Sequence > struct apply \ 75 { \ 76 typedef result type; \ 77 }; \ 78 }; \ 79 /**/ 80 81 // a sequence with nested 'begin/end' typedefs; just query them 82 AUX778076_IMPL_SPEC(begin, nested_begin_end_tag, typename Sequence::begin) 83 AUX778076_IMPL_SPEC(end, nested_begin_end_tag, typename Sequence::end) 84 85 // if a type 'T' does not contain 'begin/end' or 'tag' members 86 // and doesn't specialize either 'begin/end' or 'begin_impl/end_impl' 87 // templates, then we end up here 88 AUX778076_IMPL_SPEC(begin, non_sequence_tag, void_) 89 AUX778076_IMPL_SPEC(end, non_sequence_tag, void_) 90 AUX778076_IMPL_SPEC(begin, na, void_) 91 AUX778076_IMPL_SPEC(end, na, void_) 92 93 # undef AUX778076_IMPL_SPEC 94 95 96 BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC_IMPL(1,begin_impl) 97 BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC_IMPL(1,end_impl) 98 99 }} 100 101 #endif // BOOST_MPL_AUX_BEGIN_END_IMPL_HPP_INCLUDED 102