EVOLUTION-MANAGER
Edit File: segmented_next_impl.hpp
/*============================================================================= 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_ITERATOR_NEXT_IMPL_HPP_INCLUDED) #define BOOST_FUSION_SEGMENTED_ITERATOR_NEXT_IMPL_HPP_INCLUDED #include <boost/fusion/support/config.hpp> #include <boost/type_traits/add_const.hpp> #include <boost/type_traits/remove_reference.hpp> #include <boost/fusion/iterator/equal_to.hpp> #include <boost/fusion/container/list/cons_fwd.hpp> #include <boost/fusion/iterator/next.hpp> #include <boost/fusion/iterator/deref.hpp> namespace boost { namespace fusion { template <typename First, typename Second> struct iterator_range; template <typename Context> struct segmented_iterator; namespace detail { template <typename Sequence, typename Stack> struct segmented_begin_impl; //bool is_invalid(stack) //{ // return empty(car(stack)); //} template <typename Stack> struct is_invalid : result_of::equal_to< typename Stack::car_type::begin_type, typename Stack::car_type::end_type > {}; ////Advance the first iterator in the seq at the ////top of a stack of iterator ranges. Return the ////new stack. //auto pop_front_car(stack) //{ // return cons(iterator_range(next(begin(car(stack))), end(car(stack))), cdr(stack)); //} template <typename Stack> struct pop_front_car { typedef iterator_range< typename result_of::next< typename Stack::car_type::begin_type >::type , typename Stack::car_type::end_type > car_type; typedef cons<car_type, typename Stack::cdr_type> type; BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED static type call(Stack const & stack) { return type( car_type(fusion::next(stack.car.first), stack.car.last), stack.cdr); } }; template < typename Stack, typename Next = typename pop_front_car<Stack>::type, bool IsInvalid = is_invalid<Next>::value, int StackSize = Stack::size::value> struct segmented_next_impl_recurse; // Handle the case where the top of the stack has no usable //auto segmented_next_impl_recurse3(stack) //{ // if (size(stack) == 1) // return cons(iterator_range(end(car(stack)), end(car(stack))), nil_); // else // return segmented_next_impl_recurse(stack.cdr); //} template < typename Stack, int StackSize = Stack::size::value> struct segmented_next_impl_recurse3 { typedef segmented_next_impl_recurse<typename Stack::cdr_type> impl; typedef typename impl::type type; BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED static type call(Stack const & stack) { return impl::call(stack.cdr); } }; template <typename Stack> struct segmented_next_impl_recurse3<Stack, 1> { typedef typename Stack::car_type::end_type end_type; typedef iterator_range<end_type, end_type> range_type; typedef cons<range_type> type; BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED static type call(Stack const & stack) { return type(range_type(stack.car.last, stack.car.last)); } }; //auto segmented_next_impl_recurse2(stack) //{ // auto res = segmented_begin_impl(front(car(stack)), stack); // if (is_invalid(res)) // return segmented_next_impl_recurse3(stack); // else // return res; //} template < typename Stack, typename Sequence = typename remove_reference< typename add_const< typename result_of::deref< typename Stack::car_type::begin_type >::type >::type >::type, typename Result = typename segmented_begin_impl<Sequence, Stack>::type, bool IsInvalid = is_invalid<Result>::value> struct segmented_next_impl_recurse2 { typedef segmented_next_impl_recurse3<Stack> impl; typedef typename impl::type type; BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED static type call(Stack const & stack) { return impl::call(stack); } }; template <typename Stack, typename Sequence, typename Result> struct segmented_next_impl_recurse2<Stack, Sequence, Result, false> { typedef Result type; BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED static type call(Stack const & stack) { return segmented_begin_impl<Sequence, Stack>::call(*stack.car.first, stack); } }; //auto segmented_next_impl_recurse(stack) //{ // auto next = pop_front_car(stack); // if (is_invalid(next)) // if (1 == size(stack)) // return next; // else // return segmented_next_impl_recurse(cdr(stack)); // else // return segmented_next_impl_recurse2(next) //} template <typename Stack, typename Next, bool IsInvalid, int StackSize> struct segmented_next_impl_recurse { typedef typename segmented_next_impl_recurse<typename Stack::cdr_type>::type type; BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED static type call(Stack const& stack) { return segmented_next_impl_recurse<typename Stack::cdr_type>::call(stack.cdr); } }; template <typename Stack, typename Next> struct segmented_next_impl_recurse<Stack, Next, true, 1> { typedef Next type; BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED static type call(Stack const & stack) { return pop_front_car<Stack>::call(stack); } }; template <typename Stack, typename Next, int StackSize> struct segmented_next_impl_recurse<Stack, Next, false, StackSize> { typedef segmented_next_impl_recurse2<Next> impl; typedef typename impl::type type; BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED static type call(Stack const & stack) { return impl::call(pop_front_car<Stack>::call(stack)); } }; //auto segmented_next_impl(stack) //{ // // car(stack) is a seq of values, not a seq of segments // auto next = pop_front_car(stack); // if (is_invalid(next)) // return segmented_next_impl_recurse(cdr(next)); // else // return next; //} template < typename Stack, typename Next = typename pop_front_car<Stack>::type, bool IsInvalid = is_invalid<Next>::value> struct segmented_next_impl_aux { typedef segmented_next_impl_recurse<typename Stack::cdr_type> impl; typedef typename impl::type type; BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED static type call(Stack const & stack) { return impl::call(stack.cdr); } }; template <typename Stack, typename Next> struct segmented_next_impl_aux<Stack, Next, false> { typedef Next type; BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED static type call(Stack const & stack) { return pop_front_car<Stack>::call(stack); } }; template <typename Stack> struct segmented_next_impl : segmented_next_impl_aux<Stack> {}; } }} #endif