diff --git a/include/boost/fusion/algorithm/transformation/pop_back.hpp b/include/boost/fusion/algorithm/transformation/pop_back.hpp index 6eb743fd..4da08710 100644 --- a/include/boost/fusion/algorithm/transformation/pop_back.hpp +++ b/include/boost/fusion/algorithm/transformation/pop_back.hpp @@ -1,7 +1,7 @@ /*============================================================================= - Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2001-2011 Joel de Guzman - Distributed under the Boost Software License, Version 1.0. (See accompanying + 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(FUSION_POP_BACK_09172005_1038) @@ -10,22 +10,87 @@ #include #include #include -#include +#include +#include +#include +#include +#include +#include namespace boost { namespace fusion { + template + struct pop_back_iterator + : iterator_adapter< + pop_back_iterator + , Iterator_> + { + typedef iterator_adapter< + pop_back_iterator + , Iterator_> + base_type; + + static bool const is_last = IsLast; + + pop_back_iterator(Iterator_ const& iterator_base) + : base_type(iterator_base) {} + + template + pop_back_iterator(pop_back_iterator const& rhs) + : base_type(rhs.iterator_base) {} + + template + struct make + { + typedef pop_back_iterator type; + + static type + call(BaseIterator const& i) + { + return type(i); + } + }; + + template + struct equal_to + : result_of::equal_to< + typename mpl::if_c<(I1::is_last|I2::is_last) + , typename result_of::next< + typename I1::iterator_base_type>::type + , typename I1::iterator_base_type>::type + , typename I2::iterator_base_type + > + {}; + + template + struct distance + : mpl::minus< + typename result_of::distance< + typename First::iterator_base_type + , typename Last::iterator_base_type + >::type + , mpl::int_<(Last::is_last?1:0)> + >::type + {}; + }; + namespace result_of { template struct pop_back { - typedef - iterator_range< - typename begin::type - , typename prior< - typename end::type - >::type - > + BOOST_MPL_ASSERT_NOT((result_of::empty)); + + typedef pop_back_iterator< + typename begin::type, false> + begin_type; + + typedef pop_back_iterator< + typename end::type, true> + end_type; + + typedef + iterator_range type; }; } @@ -34,8 +99,15 @@ namespace boost { namespace fusion inline typename result_of::pop_back::type pop_back(Sequence const& seq) { - typedef typename result_of::pop_back::type result; - return result(fusion::begin(seq), fusion::prior(fusion::end(seq))); + typedef result_of::pop_back comp; + typedef typename comp::begin_type begin_type; + typedef typename comp::end_type end_type; + typedef typename comp::type result; + + return result( + begin_type(fusion::begin(seq)) + , end_type(fusion::end(seq)) + ); } }}