mirror of
https://github.com/boostorg/property_map.git
synced 2026-01-19 04:22:15 +00:00
Added compose_property_map from Guillaume Pinot
[SVN r83037]
This commit is contained in:
144
doc/compose_property_map.html
Normal file
144
doc/compose_property_map.html
Normal 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<FPMap, GPMap>
|
||||
</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 <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;
|
||||
}
|
||||
</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& f, const GPMap& g);
|
||||
</pre>
|
||||
Constructor.
|
||||
|
||||
<hr>
|
||||
|
||||
<h3>Non-Member functions</h3>
|
||||
|
||||
<hr>
|
||||
|
||||
<pre>
|
||||
template <class FPMap, class GPMap>
|
||||
compose_property_map<FPMap, GPMap>
|
||||
make_compose_property_map(const FPMap& f, const GPMap& 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 © 2013</td>
|
||||
<td>Guillaume Pinot</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -292,6 +292,7 @@ functions are defined in <tt><boost/property_map/property_map.hpp></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>
|
||||
|
||||
36
example/compose_property_map_example.cpp
Normal file
36
example/compose_property_map_example.cpp
Normal 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;
|
||||
}
|
||||
81
include/boost/property_map/compose_property_map.hpp
Normal file
81
include/boost/property_map/compose_property_map.hpp
Normal 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
|
||||
@@ -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 ]
|
||||
|
||||
101
test/compose_property_map_test.cpp
Normal file
101
test/compose_property_map_test.cpp
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user