Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion build.jam
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 5 additions & 4 deletions include/boost/property_map/compose_property_map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include <boost/property_map/property_map.hpp>
#include <boost/type_traits.hpp>
#include <type_traits>

namespace boost {

Expand Down Expand Up @@ -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<reference> >,
inline friend typename std::conditional<
!boost::is_reference<reference>::value,
value_type,
typename boost::mpl::if_<
boost::is_const<reference>,
typename std::conditional<
boost::is_const<reference>::value,
reference,
const value_type&
>::type
Expand Down
11 changes: 6 additions & 5 deletions include/boost/property_map/dynamic_property_map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
#include <boost/any.hpp>
#include <boost/function/function3.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/type.hpp>
#include <boost/type_index.hpp>
#include <boost/smart_ptr.hpp>
Expand All @@ -33,6 +32,7 @@
#include <sstream>
#include <stdexcept>
#include <string>
#include <type_traits>
#include <typeinfo>

namespace boost {
Expand Down Expand Up @@ -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_<true>)
void do_put(const any& in_key, const any& in_value, std::true_type)
{
using boost::put;

Expand All @@ -163,7 +163,7 @@ class dynamic_property_map_adaptor : public dynamic_property_map
}
}

void do_put(const any&, const any&, mpl::bool_<false>)
void do_put(const any&, const any&, std::false_type)
{
BOOST_THROW_EXCEPTION(dynamic_const_put_error());
}
Expand All @@ -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<category*,
writable_property_map_tag*>::value)>());
std::integral_constant<bool,
is_convertible<category*,
writable_property_map_tag*>::value>());
}

const std::type_info& key() const BOOST_OVERRIDE { return typeid(key_type); }
Expand Down
10 changes: 3 additions & 7 deletions include/boost/property_map/function_property_map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@
#include <boost/property_map/property_map.hpp>
#include <boost/type_traits.hpp>
#include <boost/utility/result_of.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/not.hpp>
#include <type_traits>
#include <utility>

namespace boost {
Expand All @@ -30,11 +29,8 @@ class function_property_map: public put_get_helper<Ret, function_property_map<Fu
typedef Ret reference;
typedef typename boost::remove_cv<typename boost::remove_reference<Ret>::type>::type value_type;

typedef typename boost::mpl::if_<
boost::mpl::and_<
boost::is_reference<Ret>,
boost::mpl::not_<boost::is_const<Ret> >
>,
typedef typename std::conditional<
boost::is_reference<Ret>::value && !boost::is_const<Ret>::value,
boost::lvalue_property_map_tag,
boost::readable_property_map_tag>::type
category;
Expand Down
45 changes: 25 additions & 20 deletions include/boost/property_map/property_map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,30 +19,34 @@
#include <boost/concept/assert.hpp>
#include <boost/concept_check.hpp>
#include <boost/concept_archetype.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/make_void.hpp>
#include <type_traits>

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 <class T, class = void> struct has_key_type : std::false_type {};
template <class T> struct has_key_type<T, boost::void_t<typename T::key_type> > : std::true_type {};

template <class T, class = void> struct has_value_type : std::false_type {};
template <class T> struct has_value_type<T, boost::void_t<typename T::value_type> > : std::true_type {};

template <class T, class = void> struct has_reference : std::false_type {};
template <class T> struct has_reference<T, boost::void_t<typename T::reference> > : std::true_type {};

template <class T, class = void> struct has_category : std::false_type {};
template <class T> struct has_category<T, boost::void_t<typename T::category> > : std::true_type {};

template<class PA>
struct is_property_map :
boost::mpl::and_<
has_key_type<PA>,
has_value_type<PA>,
has_reference<PA>,
has_category<PA>
std::integral_constant<bool,
has_key_type<PA>::value &&
has_value_type<PA>::value &&
has_reference<PA>::value &&
has_category<PA>::value
>
{};

Expand All @@ -58,7 +62,7 @@ namespace boost {

template <typename PA>
struct property_traits :
boost::mpl::if_<is_property_map<PA>,
std::conditional<is_property_map<PA>::value,
default_property_traits<PA>,
null_property_traits>::type
{};
Expand Down Expand Up @@ -232,9 +236,9 @@ namespace boost {
BOOST_CONCEPT_ASSERT((ConvertibleConcept<Category, LvalueTag>));

typedef typename property_traits<PMap>::value_type value_type;
BOOST_MPL_ASSERT((boost::mpl::or_<
boost::is_same<const value_type&, reference>,
boost::is_same<value_type&, reference> >));
static_assert(boost::is_same<const value_type&, reference>::value ||
boost::is_same<value_type&, reference>::value,
"lvalue property map reference must be value_type& or const value_type&");

reference ref = pmap[k];
ignore_unused_variable_warning(ref);
Expand Down Expand Up @@ -266,7 +270,8 @@ namespace boost {
BOOST_CONCEPT_ASSERT((ConvertibleConcept<Category, LvalueTag>));

typedef typename property_traits<PMap>::value_type value_type;
BOOST_MPL_ASSERT((boost::is_same<value_type&, reference>));
static_assert(boost::is_same<value_type&, reference>::value,
"mutable lvalue property map reference must be value_type&");

reference ref = pmap[k];
ignore_unused_variable_warning(ref);
Expand Down
14 changes: 8 additions & 6 deletions include/boost/property_map/property_map_iterator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@

#include <boost/property_map/property_map.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <type_traits>

namespace boost {

Expand Down Expand Up @@ -92,11 +92,13 @@ namespace boost {
} // namespace detail

template <class PropertyMap, class Iterator>
struct property_map_iterator_generator :
mpl::if_< is_same< typename property_traits<PropertyMap>::category, lvalue_property_map_tag>,
detail::lvalue_pmap_iter<Iterator, PropertyMap>,
detail::readable_pmap_iter<Iterator, PropertyMap> >
{};
struct property_map_iterator_generator
{
typedef typename std::conditional<
is_same< typename property_traits<PropertyMap>::category, lvalue_property_map_tag>::value,
detail::lvalue_pmap_iter<Iterator, PropertyMap>,
detail::readable_pmap_iter<Iterator, PropertyMap> >::type type;
};

template <class PropertyMap, class Iterator>
typename property_map_iterator_generator<PropertyMap, Iterator>::type
Expand Down
10 changes: 3 additions & 7 deletions include/boost/property_map/transform_value_property_map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@
#include <boost/property_map/property_map.hpp>
#include <boost/type_traits.hpp>
#include <boost/utility/result_of.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/not.hpp>
#include <type_traits>
#include <utility>

namespace boost {
Expand All @@ -30,11 +29,8 @@ class transform_value_property_map: public put_get_helper<Ret, transform_value_p
typedef Ret reference;
typedef typename boost::remove_cv<typename boost::remove_reference<Ret>::type>::type value_type;

typedef typename boost::mpl::if_<
boost::mpl::and_<
boost::is_reference<Ret>,
boost::mpl::not_<boost::is_const<Ret> >
>,
typedef typename std::conditional<
boost::is_reference<Ret>::value && !boost::is_const<Ret>::value,
boost::lvalue_property_map_tag,
boost::readable_property_map_tag>::type
category;
Expand Down
1 change: 1 addition & 0 deletions test/Jamfile.v2
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ test-suite property_map
[ run dynamic_properties_test.cpp : : : <define>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 ]
;
63 changes: 63 additions & 0 deletions test/property_map_iterator_test.cpp
Original file line number Diff line number Diff line change
@@ -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 <boost/property_map/property_map_iterator.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/core/lightweight_test.hpp>
#include <cstddef>
#include <vector>

int main()
{
using namespace boost;

// Readable property map: identity_property_map -> readable_pmap_iter branch.
{
using key_iterator = std::vector<std::size_t>::iterator;
using pmap_iterator =
property_map_iterator_generator<identity_property_map, key_iterator>::type;

std::vector<std::size_t> 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<std::ptrdiff_t>::iterator;
using pmap_iterator =
property_map_iterator_generator<double*, key_iterator>::type;

double values[5] = {10., 11., 12., 13., 14.};
double* pmap = values;

std::vector<std::ptrdiff_t> 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<double>(idx));
}
BOOST_TEST(idx == 5);
}

return boost::report_errors();
}
Loading