text: /*=============================================================================
      Copyright (c) 2011 Eric Niebler
  
      Distributed under the Boost Software License, Version 1.0. (See accompanying
      file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  ==============================================================================*/
  #if !defined(BOOST_FUSION_SEGMENTED_BEGIN_IMPL_HPP_INCLUDED)
  #define BOOST_FUSION_SEGMENTED_BEGIN_IMPL_HPP_INCLUDED
  
  #include <boost/fusion/support/config.hpp>
  #include <boost/type_traits/remove_const.hpp>
  #include <boost/fusion/container/list/cons_fwd.hpp>
  #include <boost/fusion/sequence/intrinsic_fwd.hpp>
  #include <boost/fusion/support/is_segmented.hpp>
  #include <boost/fusion/sequence/intrinsic/detail/segmented_end_impl.hpp>
  #include <boost/fusion/support/detail/segmented_fold_until_impl.hpp>
  
  namespace boost { namespace fusion
  {
      template <typename First, typename Last>
      struct iterator_range;
  }}
  
  namespace boost { namespace fusion { namespace detail
  {
      struct segmented_begin_fun
      {
          template <typename Sequence, typename State, typename Context>
          struct apply
          {
              typedef
                  iterator_range<
                      typename fusion::result_of::begin<Sequence>::type
                    , typename fusion::result_of::end<Sequence>::type
                  >
              range_type;
  
              typedef cons<range_type, Context> type;
              typedef mpl::false_ continue_type;
  
              BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
              static type call(Sequence& seq, State const&, Context const& context, segmented_begin_fun)
              {
                  return type(range_type(fusion::begin(seq), fusion::end(seq)), context);
              }
          };
      };
  
      template <typename Sequence, typename Stack, bool IsSegmented = traits::is_segmented<Sequence>::type::value>
      struct segmented_begin_impl_aux
      {
          typedef
              segmented_end_impl<Sequence, Stack>
          end_impl;
  
          typedef
              segmented_fold_until_impl<
                  Sequence
                , typename end_impl::type
                , Stack
                , segmented_begin_fun
              >
          fold_impl;
  
          typedef typename fold_impl::type type;
  
          BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
          static type call(Sequence& seq, Stack const& stack)
          {
              return fold_impl::call(seq, end_impl::call(seq, stack), stack, segmented_begin_fun());
          }
      };
  
      template <typename Sequence, typename Stack>
      struct segmented_begin_impl_aux<Sequence, Stack, false>
      {
          typedef typename result_of::begin<Sequence>::type  begin_type;
          typedef typename result_of::end<Sequence>::type    end_type;
          typedef iterator_range<begin_type, end_type>    pair_type;
          typedef cons<pair_type, Stack>                  type;
  
          BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
          static type call(Sequence& seq, Stack stack)
          {
              return type(pair_type(fusion::begin(seq), fusion::end(seq)), stack);
          }
      };
  
      template <typename Sequence, typename Stack>
      struct segmented_begin_impl
        : segmented_begin_impl_aux<Sequence, Stack>
      {};
  
  }}}
  
  #endif
  