From 1c02715e4990299d37dea1fb32bcca6f1e927cd4 Mon Sep 17 00:00:00 2001 From: Bruno Dutra Date: Mon, 9 Feb 2015 00:04:07 -0200 Subject: [PATCH 1/5] Fix to bug 11001 According to reference, insert_range should work for any Extensible sequence or Extensible Associative sequence, but the default implementation of insert_range_impl assumes a front_inserter is defined for the given sequence, but neither Extensible nor every Extensible Associative sequences are required to also be a Front Extensible sequence. This fix rely only on insert, which is defined for every Extensible sequence. --- include/boost/mpl/aux_/insert_range_impl.hpp | 35 +++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/include/boost/mpl/aux_/insert_range_impl.hpp b/include/boost/mpl/aux_/insert_range_impl.hpp index baffb54..4595468 100644 --- a/include/boost/mpl/aux_/insert_range_impl.hpp +++ b/include/boost/mpl/aux_/insert_range_impl.hpp @@ -14,9 +14,10 @@ // $Date$ // $Revision$ -#include +#include +#include +#include #include -#include #include #include #include @@ -43,29 +44,31 @@ struct insert_range_impl > struct apply #if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING) - : reverse_copy< - joint_view< + : fold< + joint_view< iterator_range::type,Pos> - , joint_view< + , joint_view< Range , iterator_range::type> > > - , front_inserter< typename clear::type > + , typename clear::type + , insert<_1, end<_1>, _2> > { #else { - typedef typename reverse_copy< - joint_view< - iterator_range::type,Pos> - , joint_view< - Range - , iterator_range::type> - > - > - , front_inserter< typename clear::type > - >::type type; + typedef typename fold< + joint_view< + iterator_range::type,Pos> + , joint_view< + Range + , iterator_range::type> + > + > + , typename clear::type + , insert<_1, end<_1>, _2> + >::type type; #endif }; }; From c7798600d67acb49d398ebe90e9d7e2fcfe5738c Mon Sep 17 00:00:00 2001 From: Bruno Dutra Date: Mon, 9 Feb 2015 20:48:55 -0200 Subject: [PATCH 2/5] Inserting elements at the beginning of Sequence, rather than at the end This way we take advantage of the constant-time insertion and removal of elements at the beginning of Front Extensible sequences, such as list. This implementation is closer to the original. --- include/boost/mpl/aux_/insert_range_impl.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/mpl/aux_/insert_range_impl.hpp b/include/boost/mpl/aux_/insert_range_impl.hpp index 4595468..fa43315 100644 --- a/include/boost/mpl/aux_/insert_range_impl.hpp +++ b/include/boost/mpl/aux_/insert_range_impl.hpp @@ -44,7 +44,7 @@ struct insert_range_impl > struct apply #if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING) - : fold< + : reverse_fold< joint_view< iterator_range::type,Pos> , joint_view< @@ -53,12 +53,12 @@ struct insert_range_impl > > , typename clear::type - , insert<_1, end<_1>, _2> + , insert<_1, begin<_1>, _2> > { #else { - typedef typename fold< + typedef typename reverse_fold< joint_view< iterator_range::type,Pos> , joint_view< @@ -67,7 +67,7 @@ struct insert_range_impl > > , typename clear::type - , insert<_1, end<_1>, _2> + , insert<_1, begin<_1>, _2> >::type type; #endif }; From fc18efc259d115c70631cca08a347d28e3fd0c03 Mon Sep 17 00:00:00 2001 From: Bruno Dutra Date: Tue, 10 Feb 2015 20:59:54 -0200 Subject: [PATCH 3/5] Specializing insert_range for aux::map_tag Taking advantage of the fact that order of insertion doesn't really matter for associative sequences. Comparing to the default implementation, which at any rate does work for associative sequences, this specialization essencially avoids reinserting every element of Sequence into a new sequence, besides the fact no joint_view nor iterator_range needs to be instantiated. --- .../boost/mpl/map/aux_/insert_range_impl.hpp | 41 +++++++++++++++++++ include/boost/mpl/map/map0.hpp | 1 + 2 files changed, 42 insertions(+) create mode 100644 include/boost/mpl/map/aux_/insert_range_impl.hpp diff --git a/include/boost/mpl/map/aux_/insert_range_impl.hpp b/include/boost/mpl/map/aux_/insert_range_impl.hpp new file mode 100644 index 0000000..f1f0437 --- /dev/null +++ b/include/boost/mpl/map/aux_/insert_range_impl.hpp @@ -0,0 +1,41 @@ + +#ifndef BOOST_MPL_MAP_AUX_INSERT_RANGE_IMPL_HPP_INCLUDED +#define BOOST_MPL_MAP_AUX_INSERT_RANGE_IMPL_HPP_INCLUDED + +// Copyright Bruno Dutra 2015 +// +// 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) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +template<> +struct insert_range_impl< aux::map_tag > +{ + template< + typename Sequence + , typename /*Pos*/ + , typename Range + > + struct apply + : fold > + { + }; +}; + +}} + +#endif // BOOST_MPL_MAP_AUX_INSERT_RANGE_IMPL_HPP_INCLUDED diff --git a/include/boost/mpl/map/map0.hpp b/include/boost/mpl/map/map0.hpp index e1ea897..88ed4b7 100644 --- a/include/boost/mpl/map/map0.hpp +++ b/include/boost/mpl/map/map0.hpp @@ -19,6 +19,7 @@ #include //#include #include +#include #include #include #include From f807edab2e1c3c2255b765b34fb97a4c9fa5fc5d Mon Sep 17 00:00:00 2001 From: Bruno Dutra Date: Sat, 21 Feb 2015 19:42:38 -0200 Subject: [PATCH 4/5] Specializing insert_range for aux::set_tag as well Follows the same rationale as for maps. --- .../boost/mpl/set/aux_/insert_range_impl.hpp | 41 +++++++++++++++++++ include/boost/mpl/set/set0.hpp | 1 + 2 files changed, 42 insertions(+) create mode 100644 include/boost/mpl/set/aux_/insert_range_impl.hpp diff --git a/include/boost/mpl/set/aux_/insert_range_impl.hpp b/include/boost/mpl/set/aux_/insert_range_impl.hpp new file mode 100644 index 0000000..f7150a8 --- /dev/null +++ b/include/boost/mpl/set/aux_/insert_range_impl.hpp @@ -0,0 +1,41 @@ + +#ifndef BOOST_MPL_SET_AUX_INSERT_RANGE_IMPL_HPP_INCLUDED +#define BOOST_MPL_SET_AUX_INSERT_RANGE_IMPL_HPP_INCLUDED + +// Copyright Bruno Dutra 2015 +// +// 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) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +template<> +struct insert_range_impl< aux::set_tag > +{ + template< + typename Sequence + , typename /*Pos*/ + , typename Range + > + struct apply + : fold > + { + }; +}; + +}} + +#endif // BOOST_MPL_SET_AUX_INSERT_RANGE_IMPL_HPP_INCLUDED diff --git a/include/boost/mpl/set/set0.hpp b/include/boost/mpl/set/set0.hpp index 8403731..1c424e4 100644 --- a/include/boost/mpl/set/set0.hpp +++ b/include/boost/mpl/set/set0.hpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include From 77cda02d859adfba217b581076314daddda365e6 Mon Sep 17 00:00:00 2001 From: Bruno Dutra Date: Sat, 21 Feb 2015 19:44:20 -0200 Subject: [PATCH 5/5] Adding a new test case for insert_range. Tests whether insert_range works with set, set_c and map as it should. --- test/insert_range.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/test/insert_range.cpp b/test/insert_range.cpp index 65e16fa..865017b 100644 --- a/test/insert_range.cpp +++ b/test/insert_range.cpp @@ -15,9 +15,17 @@ #include #include #include +#include +#include +#include #include #include #include +#include +#include +#include +#include +#include #include @@ -33,3 +41,33 @@ MPL_TEST_CASE() typedef insert_range< list0<>,end< list0<> >::type,list1 >::type result2; MPL_ASSERT_RELATION( size::value, ==, 1 ); } + +template +void test_associative() +{ + typedef typename insert_range< A,typename end< A >::type,B >::type C; + + MPL_ASSERT_RELATION( size::value, <=, (size::value + size::value) ); + MPL_ASSERT(( fold< joint_view< A,B >,true_,and_< _1,contains< C,_2 > > > )); +} + +MPL_TEST_CASE() +{ + typedef set3< short,int,long > signed_integers; + typedef set3< unsigned short,unsigned int,unsigned long > unsigned_integers; + test_associative(); + + typedef set_c< int,1,3,5,7,9 > odds; + typedef set_c< int,0,2,4,6,8 > evens; + test_associative(); + + typedef map2< + pair< void,void* > + , pair< int,int* > + > pointers; + typedef map2< + pair< void const,void const* > + , pair< int const,int const* > + > pointers_to_const; + test_associative(); +}