begin_end_impl.hpp 2.6 KB

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