|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r81428 - in sandbox/type_erasure: boost/type_erasure libs/type_erasure/doc libs/type_erasure/example
From: steven_at_[hidden]
Date: 2012-11-19 16:19:36
Author: steven_watanabe
Date: 2012-11-19 16:19:34 EST (Mon, 19 Nov 2012)
New Revision: 81428
URL: http://svn.boost.org/trac/boost/changeset/81428
Log:
Doc update
Text files modified:
sandbox/type_erasure/boost/type_erasure/any.hpp | 17 ++++++-
sandbox/type_erasure/boost/type_erasure/param.hpp | 12 ++++-
sandbox/type_erasure/boost/type_erasure/rebind_any.hpp | 2
sandbox/type_erasure/libs/type_erasure/doc/type_erasure.qbk | 84 ++++++++++++++++++++++++++++-----------
sandbox/type_erasure/libs/type_erasure/example/basic.cpp | 12 +++++
sandbox/type_erasure/libs/type_erasure/example/compose.cpp | 3
sandbox/type_erasure/libs/type_erasure/example/concept_map.cpp | 8 +++
sandbox/type_erasure/libs/type_erasure/example/custom.cpp | 11 +++-
sandbox/type_erasure/libs/type_erasure/example/multi.cpp | 3
sandbox/type_erasure/libs/type_erasure/example/overload.cpp | 8 +-
10 files changed, 119 insertions(+), 41 deletions(-)
Modified: sandbox/type_erasure/boost/type_erasure/any.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/any.hpp (original)
+++ sandbox/type_erasure/boost/type_erasure/any.hpp 2012-11-19 16:19:34 EST (Mon, 19 Nov 2012)
@@ -117,10 +117,13 @@
#endif
/**
- * The class template @ref any provides runtime polymorphism.
+ * The class template @ref any can store any object that
+ * models a specific @c Concept. It dispatches all
+ * the function defined by the @c Concept to the contained type
+ * at runtime.
*
* \tparam Concept The concept that the type should model.
- * \tparam T A placeholder specifying which type this is.
+ * \tparam T A @ref placeholder specifying which type this is.
*
* @c Concept is defined as follows:
* - The built-in concepts provided by the library are valid concepts.
@@ -161,6 +164,8 @@
}
/**
* Constructs an @ref any to hold a copy of @c data.
+ * The @c Concept will be instantiated with the
+ * placeholder @c T bound to U.
*
* \param data The object to construct the @ref any from.
*
@@ -182,7 +187,8 @@
data(data_arg)
{}
/**
- * Constructs an @ref any to hold a copy of @c data.
+ * Constructs an @ref any to hold a copy of @c data
+ * with explicitly specified placeholder bindings.
*
* \param data The object to construct the @ref any from.
* \param binding Specifies the actual types that
@@ -192,6 +198,7 @@
* \pre @c U must be \CopyConstructible.
* \pre @c Map is an MPL map with an entry for every
* placeholder referred to by @c Concept.
+ * \pre @c @c T must map to @c U in @c Map.
*
* \throws std::bad_alloc or whatever that the copy
* constructor of @c U throws.
@@ -237,6 +244,7 @@
* \param other The object to make a copy of.
*
* \pre @c Concept must contain @ref constructible<T(const T&)>.
+ * (This is included in @ref copy_constructible<T>)
*
* \throws std::bad_alloc or whatever that the copy
* constructor of the contained type throws.
@@ -285,7 +293,8 @@
* Constructs an @ref any from another @ref any.
*
* \param other The object to make a copy of.
- * \param binding Specifies the mapping between the two concepts.
+ * \param binding Specifies the mapping between the placeholders
+ * used by the two concepts.
*
* \pre @c Concept must contain @ref constructible<T(const T&)>.
* \pre @c Map must be an MPL map with keys for all the placeholders
Modified: sandbox/type_erasure/boost/type_erasure/param.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/param.hpp (original)
+++ sandbox/type_erasure/boost/type_erasure/param.hpp 2012-11-19 16:19:34 EST (Mon, 19 Nov 2012)
@@ -75,7 +75,7 @@
#endif
/**
- * \brief A proxy to help with overload resolution for functions
+ * \brief A wrapper to help with overload resolution for functions
* operating on an @ref any.
*
* The template arguments are interpreted in
@@ -219,10 +219,16 @@
#endif
-/** \brief Metafunction that creates a @ref param.
+/**
+ * \brief Metafunction that creates a @ref param.
*
* If @c T is a (cv/reference qualifed) placeholder,
- * returns @ref param<@ref concept_of "concept_of"<Any>::type, T>, otherwise, returns T.
+ * returns @ref param<@ref concept_of "concept_of"<Any>::type, T>,
+ * otherwise, returns T. This metafunction is intended
+ * to be used for function arguments in specializations of
+ * @ref concept_interface.
+ *
+ * \see derived, rebind_any
*/
template<class Any, class T>
struct as_param {
Modified: sandbox/type_erasure/boost/type_erasure/rebind_any.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/rebind_any.hpp (original)
+++ sandbox/type_erasure/boost/type_erasure/rebind_any.hpp 2012-11-19 16:19:34 EST (Mon, 19 Nov 2012)
@@ -38,6 +38,8 @@
* rebind_any<any<Concept>, _b&>::type -> any<Concept, _b&>
* rebind_any<any<Concept>, int>::type -> int
* \endcode
+ *
+ * @see derived, as_param
*/
template<class Any, class T>
struct rebind_any
Modified: sandbox/type_erasure/libs/type_erasure/doc/type_erasure.qbk
==============================================================================
--- sandbox/type_erasure/libs/type_erasure/doc/type_erasure.qbk (original)
+++ sandbox/type_erasure/libs/type_erasure/doc/type_erasure.qbk 2012-11-19 16:19:34 EST (Mon, 19 Nov 2012)
@@ -71,12 +71,13 @@
[section:introduction Introduction]
-The TypeErasure library provides runtime polymorphism
-in C++, superior to that provided by the core language.
-
-We have two distinct kinds of polymorphism built in to C++,
-virtual functions and templates, which each have
-their own advantages and disadvantages.
+The Boost.TypeErasure library provides runtime polymorphism
+in C++ that is more flexible than that provided by the
+core language.
+
+C++ has two distinct kinds of polymorphism,
+virtual functions and templates, which each has
+its own advantages and disadvantages.
* Virtual functions are not resolved until runtime,
while templates are always resolved at compile
@@ -112,13 +113,9 @@
Virtual functions aren't really able to
express such constraints.
-The Boost.TypeErasure library provides another set
-of trade-offs. As with virtual functions, dispatching
-occurs at runtime and you can define a function once
-in a source file. The requirements are stated up front
-in the form of a Concept. Like templates, the library
-supports value semantics, non-intrusive adaptation, and
-requirements across multiple types.
+The Boost.TypeErasure library combines the superior
+abstraction capabilities of templates, with the
+runtime flexibility of virtual functions.
Boost includes several special cases of this kind
of polymorphism:
@@ -177,16 +174,16 @@
[references]
[endsect]
-[section:construction Construction]
-[import ../example/construction.cpp]
-[construction]
-[endsect]
-
[section:multi Functions with Multiple Arguments]
[import ../example/multi.cpp]
[multi]
[endsect]
+[section:construction Construction]
+[import ../example/construction.cpp]
+[construction]
+[endsect]
+
[section:concept_map Concept Maps]
[import ../example/concept_map.cpp]
[concept_map]
@@ -215,20 +212,19 @@
[section:conceptdef Concept Definitions]
-A placeholder is any type that inherits
-publicly from __placeholder.
-
There are three kinds of concepts.
# The library defines a number of [link boost_typeerasure.predef predefined concepts].
# Any MPL Forward Sequence whose elements are
- concepts is also a concept.
+ concepts is also a concept. This allows concepts
+ to be composed easily.
# Users can define their own primitive concepts.
-Each primitive concept defines a single operation.
+Each primitive concept defines a single function.
A primitive concept must be a specialization of a
class template, with a static member function
-called apply.
+called `apply`, which will be executed when the
+function is dispatched by __call.
The template parameters of the concept
may involve placeholders. The following are
@@ -262,6 +258,45 @@
Otherwise, the argument in the unbound concept
must be the same as the argument in the bound concept.
+ // Correct.
+ template<class T = _self>
+ struct foo1 {
+ static void apply(const T& t) { t.foo(); }
+ };
+
+ // Wrong. The signature of apply is different from the
+ // primary template
+ template<>
+ struct foo1<int> {
+ static void apply(int i);
+ };
+
+ // Wrong. A concept must be a template
+ struct foo2 {
+ static void apply(const _self&);
+ };
+
+ // Wrong. apply must be static
+ template<class T = _self>
+ struct foo3 {
+ void apply(const T&);
+ };
+
+ // Wrong. apply cannot be overloaded
+ template<class T = _self>
+ struct foo3 {
+ static void apply(T&);
+ static void apply(const T&);
+ };
+
+ // Wrong. Only top level placeholders are detected
+ template<class T>
+ struct foo4;
+ template<class T>
+ struct foo4<boost::mpl::vector<T> > {
+ static void apply(const T&);
+ };
+
[endsect]
[section:predef Predefined Concepts]
@@ -278,6 +313,7 @@
[[__constructible`<Sig>`][-]]
[[__copy_constructible`<T>`][-]]
[[__destructible`<T>`][-]]
+ [[__assignable`<T, U = T>`][-]]
[[__typeid_`<T>`][-]]
]
[table:unary Unary Operators
Modified: sandbox/type_erasure/libs/type_erasure/example/basic.cpp
==============================================================================
--- sandbox/type_erasure/libs/type_erasure/example/basic.cpp (original)
+++ sandbox/type_erasure/libs/type_erasure/example/basic.cpp 2012-11-19 16:19:34 EST (Mon, 19 Nov 2012)
@@ -103,6 +103,18 @@
*/
/*`
+ The concepts created by __BOOST_TYPE_ERASURE_MEMBER take
+ a __placeholder as an optional second parameter. This
+ __placeholder defaults to `_self`. If we wanted to use a
+ different placeholder or have a constant member function,
+ we'd have to specify it explicitly.
+ */
+BOOST_TYPE_ERASURE_MEMBER((has_empty), empty, 0)
+bool is_empty(any<has_empty<bool(), const _self>, const _self&> x) {
+ return x.empty();
+}
+
+/*`
For free functions, we can use the macro __BOOST_TYPE_ERASURE_FREE.
*/
Modified: sandbox/type_erasure/libs/type_erasure/example/compose.cpp
==============================================================================
--- sandbox/type_erasure/libs/type_erasure/example/compose.cpp (original)
+++ sandbox/type_erasure/libs/type_erasure/example/compose.cpp 2012-11-19 16:19:34 EST (Mon, 19 Nov 2012)
@@ -17,7 +17,8 @@
//[compose1
/*`
- This can be generalized to define a concept that
+ The use of `mpl::vector` for concept inheritence
+ can be generalized to define a concept that
is composed of multiple other concepts. The
MPL sequence can contain as many concepts as
we need.
Modified: sandbox/type_erasure/libs/type_erasure/example/concept_map.cpp
==============================================================================
--- sandbox/type_erasure/libs/type_erasure/example/concept_map.cpp (original)
+++ sandbox/type_erasure/libs/type_erasure/example/concept_map.cpp 2012-11-19 16:19:34 EST (Mon, 19 Nov 2012)
@@ -33,6 +33,14 @@
}
}
+
+/*`
+ [note Most, but not all of the builtin concepts can be specialized.
+ Constructors, destructors, and RTTI need special treatment from the
+ library and cannot be specialized. Only primitive concepts can
+ be specialized, so the iterator concepts are also out.]
+*/
+
//]
//[concept_map
Modified: sandbox/type_erasure/libs/type_erasure/example/custom.cpp
==============================================================================
--- sandbox/type_erasure/libs/type_erasure/example/custom.cpp (original)
+++ sandbox/type_erasure/libs/type_erasure/example/custom.cpp 2012-11-19 16:19:34 EST (Mon, 19 Nov 2012)
@@ -28,7 +28,7 @@
give it two template parameters, one for the container
and one for the element type. This template must have
a static member function called apply which is used
- to dispatch the operation.
+ to execute the operation.
*/
template<class C, class T>
@@ -43,7 +43,7 @@
The second part is to customize __any so that we can call `c.push_back(10)`.
We do this by specializing __concept_interface.
The first argument is `has_push_back`, since we want to inject a member
- into every __any that uses the `push_back` concept. The second argument,
+ into every __any that uses the `has_push_back` concept. The second argument,
`Base`, is used by the library to chain multiple uses of __concept_interface
together. We have to inherit from it publicly. `Base` is also used
to get access to the full __any type. The third argument is the placeholder
@@ -51,13 +51,18 @@
we only want to insert a `push_back` member in the container,
not the value type. Thus, the third argument is the container
placeholder.
+
+ When we define `push_back` the argument type uses the metafunction
+ __as_param. This is just to handle the case where `T` is a
+ placeholder. If `T` is not a placeholder, then the metafunction
+ just returns its argument, `const T&`, unchanged.
*/
namespace boost {
namespace type_erasure {
template<class C, class T, class Base>
struct concept_interface<has_push_back<C, T>, Base, C> : Base
{
- void push_back(const T& arg)
+ void push_back(typename as_param<Base, const T&>::type arg)
{ call(has_push_back<C, T>(), *this, arg); }
};
}
Modified: sandbox/type_erasure/libs/type_erasure/example/multi.cpp
==============================================================================
--- sandbox/type_erasure/libs/type_erasure/example/multi.cpp (original)
+++ sandbox/type_erasure/libs/type_erasure/example/multi.cpp 2012-11-19 16:19:34 EST (Mon, 19 Nov 2012)
@@ -23,8 +23,7 @@
//[multi1
/*`
Operations can have more than one __any argument.
- Let's change the example from the previous section
- to use binary addition, instead of increment.
+ Let's use binary addition as an example.
*/
typedef any<
mpl::vector<
Modified: sandbox/type_erasure/libs/type_erasure/example/overload.cpp
==============================================================================
--- sandbox/type_erasure/libs/type_erasure/example/overload.cpp (original)
+++ sandbox/type_erasure/libs/type_erasure/example/overload.cpp 2012-11-19 16:19:34 EST (Mon, 19 Nov 2012)
@@ -61,7 +61,7 @@
struct concept_interface< ::foo<T, U>, Base, T, Enable>
{
typedef void _fun_defined;
- void foo(typename rebind_any<Base, const U&>::type arg)
+ void foo(typename as_param<Base, const U&>::type arg)
{
call(::foo<T, U>(), *this, arg);
}
@@ -71,7 +71,7 @@
struct concept_interface< ::foo<T, U>, Base, T, typename Base::_fun_defined>
{
using Base::foo;
- void foo(typename rebind_any<Base, const U&>::type arg)
+ void foo(typename as_param<Base, const U&>::type arg)
{
call(::foo<T, U>(), *this, arg);
}
@@ -145,8 +145,8 @@
the first argument that's a placeholder.
As you might have noticed, the argument types are a bit tricky.
In the first specialization, the first argument uses __derived
- instead of __rebind_any. The reason for this is that if we used
- __rebind_any, then we could end up violating the one definition
+ instead of __as_param. The reason for this is that if we used
+ __as_param, then we could end up violating the one definition
rule by defining the same function twice. Similarly, we use
SFINAE in the second specialization to make sure that bar is
only defined once when both arguments are placeholders. It's
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk