Added compose_property_map from Guillaume Pinot

[SVN r83037]
This commit is contained in:
Jeremiah Willcock
2013-02-19 21:39:37 +00:00
parent d1a1c25a42
commit ba703d01fd
6 changed files with 364 additions and 0 deletions

View File

@@ -0,0 +1,144 @@
<html>
<!--
Copyright (c) 2012 Guillaume Pinot
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)
-->
<head>
<title>Compose Property Map Adaptor</title>
</head>
<body bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"
alink="#ff0000">
<img src="../../../boost.png"
alt="C++ Boost" width="277" height="86">
<br Clear>
<h2><a name="sec:compose-property-map"></a>
</h2>
<pre>
compose_property_map&lt;FPMap, GPMap&gt;
</pre>
<p>
This property map is an adaptor that composes two property map. The
new property map will of the same model
as <tt>FPMap</tt>. <tt>GPMap</tt> must
model <a href="./ReadablePropertyMap.html">Readable Property Map</a>.
</p>
<h3>Example</h3>
<a href="../example/compose_property_map_example.cpp">compose_property_map_example.cpp</a>:
<pre>
#include &lt;boost/property_map/compose_property_map.hpp&gt;
#include &lt;iostream&gt;
int main()
{
const int idx[] = {2, 0, 4, 1, 3};
double v[] = {1., 3., 0., 4., 2.};
boost::compose_property_map&lt;double*, const int*&gt; cpm(v, idx);
for (int i = 0; i < 5; ++i)
std::cout << get(cpm, i) << " ";
std::cout << std::endl;
for (int i = 0; i < 5; ++i)
++cpm[i];
for (int i = 0; i < 5; ++i)
std::cout << get(cpm, i) << " ";
std::cout << std::endl;
for (int i = 0; i < 5; ++i)
put(cpm, i, 42.);
for (int i = 0; i < 5; ++i)
std::cout << get(cpm, i) << " ";
std::cout << std::endl;
return 0;
}
</pre>
<p>Output:</p>
<pre>
0 1 2 3 4
1 2 3 4 5
42 42 42 42 42
</pre>
<h3>Where Defined</h3>
<p>
<a href="../../../boost/property_map/compose_property_map.hpp"><tt>boost/property_map/compose_property_map.hpp</tt></a>
</p>
<h3>Template Parameters</h3>
<P>
<table border>
<tr>
<th>Parameter</th><th>Description</th>
</tr>
<tr>
<td><tt>FPMap</tt></td>
<td>Must be a property map of any kind.</td>
</tr>
<tr>
<td><tt>GPMap</tt></td>
<td>Must be a model of <a href="./ReadablePropertyMap.html">Readable Property Map</a>.</td>
</tr>
</table>
<H3>Members</H3>
<p>
In addition to the methods and functions required by property maps,
this class has the following members:
</p>
<hr>
<pre>
compose_property_map(const FPMap&amp; f, const GPMap&amp; g);
</pre>
Constructor.
<hr>
<h3>Non-Member functions</h3>
<hr>
<pre>
template &lt;class FPMap, class GPMap&gt;
compose_property_map&lt;FPMap, GPMap&gt;
make_compose_property_map(const FPMap&amp; f, const GPMap&amp; g);
</pre>
Returns a <tt>compose_property_map</tt> using the given property maps type.
<hr>
<br>
<hr>
<table>
<tr valign="top">
<td nowrap>Copyright &copy; 2013</td>
<td>Guillaume Pinot</td>
</tr>
</table>
</body>
</html>

View File

@@ -292,6 +292,7 @@ functions are defined in <tt>&lt;boost/property_map/property_map.hpp&gt;</tt>.
<li><a href="./vector_property_map.html">vector_property_map</a></li>
<li><a href="./ref_property_map.html">ref_property_map</a> </li>
<li><a href="./transform_value_property_map.html">transform_value_property_map</a> </li>
<li><a href="./compose_property_map.html">compose_property_map</a> </li>
</ul>
<h3>History</h3>

View File

@@ -0,0 +1,36 @@
// Copyright (C) 2013 Eurodecision
// Authors: Guillaume Pinot
//
// 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)
#include <boost/property_map/compose_property_map.hpp>
#include <iostream>
int main()
{
const int idx[] = {2, 0, 4, 1, 3};
double v[] = {1., 3., 0., 4., 2.};
boost::compose_property_map<double*, const int*> cpm(v, idx);
for (int i = 0; i < 5; ++i)
std::cout << get(cpm, i) << " ";
std::cout << std::endl;
for (int i = 0; i < 5; ++i)
++cpm[i];
for (int i = 0; i < 5; ++i)
std::cout << get(cpm, i) << " ";
std::cout << std::endl;
for (int i = 0; i < 5; ++i)
put(cpm, i, 42.);
for (int i = 0; i < 5; ++i)
std::cout << get(cpm, i) << " ";
std::cout << std::endl;
return 0;
}

View File

@@ -0,0 +1,81 @@
// Copyright (C) 2013 Eurodecision
// Authors: Guillaume Pinot
//
// 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/property_map for documentation.
#ifndef BOOST_PROPERTY_MAP_COMPOSE_PROPERTY_MAP_HPP
#define BOOST_PROPERTY_MAP_COMPOSE_PROPERTY_MAP_HPP
#include <boost/property_map/property_map.hpp>
#include <boost/type_traits.hpp>
namespace boost {
// A compose property map: make_compose_property_map(f, g)[x] == f[g[x]]
//
// g must be a readable property map.
// The category of compose_property_map(f, g) is the category of f.
template <typename FPMap, typename GPMap>
class compose_property_map
{
public:
typedef typename boost::property_traits<FPMap>::category category;
typedef typename boost::property_traits<GPMap>::key_type key_type;
typedef typename boost::property_traits<FPMap>::value_type value_type;
typedef typename boost::property_traits<FPMap>::reference reference;
inline compose_property_map(const FPMap &f_p, const GPMap &g_p):
f(f_p), g(g_p)
{}
inline compose_property_map() {}
inline reference
operator[](const key_type &v) const {
return f[get(g, v)];
}
// return type of get():
// if (reference is not a ref)
// value_type
// else if (reference is const)
// reference
// else
// const value_type&
inline friend typename boost::mpl::if_<
boost::mpl::not_< boost::is_reference<reference> >,
value_type,
typename boost::mpl::if_<
boost::is_const<reference>,
reference,
const value_type&
>::type
>::type
get(const compose_property_map &m, const key_type &k) {
return get(m.f, get(m.g, k));
}
inline friend void
put(const compose_property_map &m, const key_type &k, const value_type &v) {
put(m.f, get(m.g, k), v);
}
private:
FPMap f;
GPMap g;
};
template <class FPMap, class GPMap>
inline compose_property_map<FPMap, GPMap>
make_compose_property_map(const FPMap &f, const GPMap &g) {
return compose_property_map<FPMap, GPMap>(f, g);
}
} // namespace boost
#endif // BOOST_PROPERTY_MAP_COMPOSE_PROPERTY_MAP_HPP

View File

@@ -12,6 +12,7 @@
test-suite property_map
: [ compile property_map_cc.cpp ]
[ run compose_property_map_test.cpp ]
[ run dynamic_properties_test.cpp ]
[ run function_property_map_test.cpp ]
[ run transform_value_property_map_test.cpp ]

View File

@@ -0,0 +1,101 @@
// Copyright (C) 2013 Eurodecision
// Authors: Guillaume Pinot
//
// 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)
#include <boost/property_map/compose_property_map.hpp>
#include <boost/property_map/function_property_map.hpp>
#include <boost/test/minimal.hpp>
void concept_checks()
{
using namespace boost;
{
typedef null_archetype<> Key;
//typedef assignable_archetype<copy_constructible_archetype<> > Value;
typedef copy_constructible_archetype<assignable_archetype<> > Value;
typedef readable_property_map_archetype<Key, Key> GPMap;
typedef readable_property_map_archetype<Key, Value> FPMap;
typedef compose_property_map<FPMap, GPMap> CPM;
function_requires<ReadablePropertyMapConcept<CPM, Key> >();
}
{
typedef null_archetype<> Key;
typedef copy_constructible_archetype<assignable_archetype<> > Value;
typedef readable_property_map_archetype<Key, Key> GPMap;
typedef writable_property_map_archetype<Key, Value> FPMap;
typedef compose_property_map<FPMap, GPMap> CPM;
function_requires<WritablePropertyMapConcept<CPM, Key> >();
}
{
typedef null_archetype<> Key;
typedef copy_constructible_archetype<assignable_archetype<> > Value;
typedef readable_property_map_archetype<Key, Key> GPMap;
typedef read_write_property_map_archetype<Key, Value> FPMap;
typedef compose_property_map<FPMap, GPMap> CPM;
function_requires<ReadWritePropertyMapConcept<CPM, Key> >();
}
{
typedef null_archetype<> Key;
typedef copy_constructible_archetype<assignable_archetype<> > Value;
typedef readable_property_map_archetype<Key, Key> GPMap;
typedef lvalue_property_map_archetype<Key, Value> FPMap;
typedef compose_property_map<FPMap, GPMap> CPM;
function_requires<LvaluePropertyMapConcept<CPM, Key> >();
}
{
typedef null_archetype<> Key;
typedef copy_constructible_archetype<assignable_archetype<> > Value;
typedef readable_property_map_archetype<Key, Key> GPMap;
typedef mutable_lvalue_property_map_archetype<Key, Value> FPMap;
typedef compose_property_map<FPMap, GPMap> CPM;
function_requires<Mutable_LvaluePropertyMapConcept<CPM, Key> >();
}
}
void pointer_pmap_check()
{
const int idx[] = {2, 0, 4, 1, 3};
double v[] = {1., 3., 0., 4., 2.};
boost::compose_property_map<double*, const int*> cpm(v, idx);
for (int i = 0; i < 5; ++i) {
BOOST_CHECK(get(cpm, i) == static_cast<double>(i));
++cpm[i];
BOOST_CHECK(cpm[i] == static_cast<double>(i + 1));
put(cpm, i, 42.);
BOOST_CHECK(cpm[i] == 42.);
}
}
struct modulo_add_one {
typedef int result_type;
modulo_add_one(int m): modulo(m) {}
int operator()(int i) const {return (i + 1) % modulo;}
int modulo;
};
void readable_pmap_checks()
{
using namespace boost;
typedef function_property_map<modulo_add_one, int> modulo_add_one_pmap;
compose_property_map<modulo_add_one_pmap, modulo_add_one_pmap>
cpm(modulo_add_one(5), modulo_add_one(5));
for (int i = 0; i < 10; ++i)
BOOST_CHECK(get(cpm, i) == (i + 2) % 5);
}
int
test_main(int, char**)
{
concept_checks();
pointer_pmap_check();
readable_pmap_checks();
return 0;
}