diff --git a/CMakeLists.txt b/CMakeLists.txt index 3fe56d0..b45b0b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,6 @@ target_link_libraries(boost_property_map Boost::function Boost::iterator Boost::lexical_cast - Boost::mpl Boost::smart_ptr Boost::throw_exception Boost::type_traits diff --git a/build.jam b/build.jam index c624826..33aa7e4 100644 --- a/build.jam +++ b/build.jam @@ -14,7 +14,6 @@ constant boost_dependencies : /boost/function//boost_function /boost/iterator//boost_iterator /boost/lexical_cast//boost_lexical_cast - /boost/mpl//boost_mpl /boost/smart_ptr//boost_smart_ptr /boost/throw_exception//boost_throw_exception /boost/type_index//boost_type_index diff --git a/include/boost/property_map/compose_property_map.hpp b/include/boost/property_map/compose_property_map.hpp index 4d8941d..2b12c96 100644 --- a/include/boost/property_map/compose_property_map.hpp +++ b/include/boost/property_map/compose_property_map.hpp @@ -12,6 +12,7 @@ #include #include +#include namespace boost { @@ -47,11 +48,11 @@ class compose_property_map // reference // else // const value_type& - inline friend typename boost::mpl::if_< - boost::mpl::not_< boost::is_reference >, + inline friend typename std::conditional< + !boost::is_reference::value, value_type, - typename boost::mpl::if_< - boost::is_const, + typename std::conditional< + boost::is_const::value, reference, const value_type& >::type diff --git a/include/boost/property_map/dynamic_property_map.hpp b/include/boost/property_map/dynamic_property_map.hpp index 336f000..c81bc56 100644 --- a/include/boost/property_map/dynamic_property_map.hpp +++ b/include/boost/property_map/dynamic_property_map.hpp @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -33,6 +32,7 @@ #include #include #include +#include #include namespace boost { @@ -145,7 +145,7 @@ class dynamic_property_map_adaptor : public dynamic_property_map // in_value must either hold an object of value_type or a string that // can be converted to value_type via iostreams. - void do_put(const any& in_key, const any& in_value, mpl::bool_) + void do_put(const any& in_key, const any& in_value, std::true_type) { using boost::put; @@ -163,7 +163,7 @@ class dynamic_property_map_adaptor : public dynamic_property_map } } - void do_put(const any&, const any&, mpl::bool_) + void do_put(const any&, const any&, std::false_type) { BOOST_THROW_EXCEPTION(dynamic_const_put_error()); } @@ -187,8 +187,9 @@ class dynamic_property_map_adaptor : public dynamic_property_map void put(const any& in_key, const any& in_value) BOOST_OVERRIDE { do_put(in_key, in_value, - mpl::bool_<(is_convertible::value)>()); + std::integral_constant::value>()); } const std::type_info& key() const BOOST_OVERRIDE { return typeid(key_type); } diff --git a/include/boost/property_map/function_property_map.hpp b/include/boost/property_map/function_property_map.hpp index c8c295f..5ce1cbf 100644 --- a/include/boost/property_map/function_property_map.hpp +++ b/include/boost/property_map/function_property_map.hpp @@ -17,8 +17,7 @@ #include #include #include -#include -#include +#include #include namespace boost { @@ -30,11 +29,8 @@ class function_property_map: public put_get_helper::type>::type value_type; - typedef typename boost::mpl::if_< - boost::mpl::and_< - boost::is_reference, - boost::mpl::not_ > - >, + typedef typename std::conditional< + boost::is_reference::value && !boost::is_const::value, boost::lvalue_property_map_tag, boost::readable_property_map_tag>::type category; diff --git a/include/boost/property_map/property_map.hpp b/include/boost/property_map/property_map.hpp index 5838398..fa552f3 100644 --- a/include/boost/property_map/property_map.hpp +++ b/include/boost/property_map/property_map.hpp @@ -19,30 +19,34 @@ #include #include #include -#include -#include -#include -#include -#include #include +#include +#include namespace boost { //========================================================================= // property_traits class - BOOST_MPL_HAS_XXX_TRAIT_DEF(key_type) - BOOST_MPL_HAS_XXX_TRAIT_DEF(value_type) - BOOST_MPL_HAS_XXX_TRAIT_DEF(reference) - BOOST_MPL_HAS_XXX_TRAIT_DEF(category) - + template struct has_key_type : std::false_type {}; + template struct has_key_type > : std::true_type {}; + + template struct has_value_type : std::false_type {}; + template struct has_value_type > : std::true_type {}; + + template struct has_reference : std::false_type {}; + template struct has_reference > : std::true_type {}; + + template struct has_category : std::false_type {}; + template struct has_category > : std::true_type {}; + template struct is_property_map : - boost::mpl::and_< - has_key_type, - has_value_type, - has_reference, - has_category + std::integral_constant::value && + has_value_type::value && + has_reference::value && + has_category::value > {}; @@ -58,7 +62,7 @@ namespace boost { template struct property_traits : - boost::mpl::if_, + std::conditional::value, default_property_traits, null_property_traits>::type {}; @@ -232,9 +236,9 @@ namespace boost { BOOST_CONCEPT_ASSERT((ConvertibleConcept)); typedef typename property_traits::value_type value_type; - BOOST_MPL_ASSERT((boost::mpl::or_< - boost::is_same, - boost::is_same >)); + static_assert(boost::is_same::value || + boost::is_same::value, + "lvalue property map reference must be value_type& or const value_type&"); reference ref = pmap[k]; ignore_unused_variable_warning(ref); @@ -266,7 +270,8 @@ namespace boost { BOOST_CONCEPT_ASSERT((ConvertibleConcept)); typedef typename property_traits::value_type value_type; - BOOST_MPL_ASSERT((boost::is_same)); + static_assert(boost::is_same::value, + "mutable lvalue property map reference must be value_type&"); reference ref = pmap[k]; ignore_unused_variable_warning(ref); diff --git a/include/boost/property_map/property_map_iterator.hpp b/include/boost/property_map/property_map_iterator.hpp index a7be8af..07afa2d 100644 --- a/include/boost/property_map/property_map_iterator.hpp +++ b/include/boost/property_map/property_map_iterator.hpp @@ -10,8 +10,8 @@ #include #include -#include #include +#include namespace boost { @@ -92,11 +92,13 @@ namespace boost { } // namespace detail template - struct property_map_iterator_generator : - mpl::if_< is_same< typename property_traits::category, lvalue_property_map_tag>, - detail::lvalue_pmap_iter, - detail::readable_pmap_iter > - {}; + struct property_map_iterator_generator + { + typedef typename std::conditional< + is_same< typename property_traits::category, lvalue_property_map_tag>::value, + detail::lvalue_pmap_iter, + detail::readable_pmap_iter >::type type; + }; template typename property_map_iterator_generator::type diff --git a/include/boost/property_map/transform_value_property_map.hpp b/include/boost/property_map/transform_value_property_map.hpp index 6a7b574..d8673c3 100644 --- a/include/boost/property_map/transform_value_property_map.hpp +++ b/include/boost/property_map/transform_value_property_map.hpp @@ -17,8 +17,7 @@ #include #include #include -#include -#include +#include #include namespace boost { @@ -30,11 +29,8 @@ class transform_value_property_map: public put_get_helper::type>::type value_type; - typedef typename boost::mpl::if_< - boost::mpl::and_< - boost::is_reference, - boost::mpl::not_ > - >, + typedef typename std::conditional< + boost::is_reference::value && !boost::is_const::value, boost::lvalue_property_map_tag, boost::readable_property_map_tag>::type category; diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 7c6022c..165f5c0 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -25,4 +25,5 @@ test-suite property_map [ run dynamic_properties_test.cpp : : : BOOST_NO_RTTI=1 : dynamic_properties_no_rtti_test ] [ run function_property_map_test.cpp ] [ run transform_value_property_map_test.cpp ] + [ run property_map_iterator_test.cpp ] ; diff --git a/test/property_map_iterator_test.cpp b/test/property_map_iterator_test.cpp new file mode 100644 index 0000000..9939c05 --- /dev/null +++ b/test/property_map_iterator_test.cpp @@ -0,0 +1,63 @@ +// 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) + +// Exercises property_map_iterator.hpp: make_property_map_iterator over both +// an lvalue property map (pointer) and a readable property map (identity), +// covering both branches of property_map_iterator_generator. + +#include +#include +#include +#include +#include + +int main() +{ + using namespace boost; + + // Readable property map: identity_property_map -> readable_pmap_iter branch. + { + using key_iterator = std::vector::iterator; + using pmap_iterator = + property_map_iterator_generator::type; + + std::vector keys; + for (std::size_t i = 0; i < 5; ++i) keys.push_back(i); + + identity_property_map pmap; + std::size_t idx = 0; + pmap_iterator it = make_property_map_iterator(pmap, keys.begin()); + pmap_iterator end = make_property_map_iterator(pmap, keys.end()); + for (; it != end; ++it, ++idx) + BOOST_TEST(*it == keys[idx]); + BOOST_TEST(idx == keys.size()); + } + + // Lvalue property map: pointer -> lvalue_pmap_iter branch. + { + using key_iterator = std::vector::iterator; + using pmap_iterator = + property_map_iterator_generator::type; + + double values[5] = {10., 11., 12., 13., 14.}; + double* pmap = values; + + std::vector keys; + for (std::ptrdiff_t i = 0; i < 5; ++i) keys.push_back(i); + + std::ptrdiff_t idx = 0; + pmap_iterator it = make_property_map_iterator(pmap, keys.begin()); + pmap_iterator end = make_property_map_iterator(pmap, keys.end()); + for (; it != end; ++it, ++idx) + { + BOOST_TEST(*it == values[idx]); + // lvalue iterator yields a mutable reference. + *it += 1.0; + BOOST_TEST(values[idx] == 11.0 + static_cast(idx)); + } + BOOST_TEST(idx == 5); + } + + return boost::report_errors(); +}