123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- // Boost.TypeErasure library
- //
- // Copyright 2011 Steven Watanabe
- //
- // 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)
- //
- // $Id$
- #include <boost/type_erasure/any.hpp>
- #include <boost/type_erasure/any_cast.hpp>
- #include <boost/type_erasure/builtin.hpp>
- #include <boost/type_erasure/operators.hpp>
- #include <boost/mpl/vector.hpp>
- #include <boost/shared_ptr.hpp>
- #include <iostream>
- namespace mpl = boost::mpl;
- using namespace boost::type_erasure;
- void references1() {
- //[references1
- /*`
- To capture by reference, we simply add a reference
- to the __placeholder.
- */
- int i;
- any<typeid_<>, _self&> x(i);
- any_cast<int&>(x) = 5; // now i is 5
- /*`
- [note `_self` is the default __placeholder, so it is
- easiest to use `_self&`. We could use another
- __placeholder instead. __any`<`__typeid_`<_a>, _a&>` has
- exactly the same behavior.]
- */
- //]
- }
- void references2() {
- //[references2
- /*`
- References cannot be rebound. Just like a built-in C++ reference,
- once you've initialized it you can't change it to point to
- something else.
- ``
- int i, j;
- any<typeid_<>, _self&> x(i), y(j);
- x = y; // error
- ``
- [note As with any other operation, `x = y` for references
- acts on `i` and `j`. Assignment like this is legal
- if __assignable`<>` is in the Concept, but `x` would
- still hold a reference to `i`.]
- */
- //]
- }
- void references3() {
- //[references3
- /*`
- A reference can be bound to another __any.
- */
- typedef mpl::vector<
- copy_constructible<>,
- incrementable<>
- > requirements;
- any<requirements> x(10);
- any<requirements, _self&> y(x);
- ++y; // x is now 11
- //]
- }
- void references4() {
- //[references4
- /*`
- If a reference is used after the underlying object
- goes out of scope or is reset, the behavior is undefined.
- */
- typedef mpl::vector<
- copy_constructible<>,
- incrementable<>,
- relaxed
- > requirements;
- any<requirements> x(10);
- any<requirements, _self&> y(x);
- x = 1.0;
- ++y; // undefined behavior.
- //]
- }
- void references5() {
- typedef mpl::vector<
- copy_constructible<>,
- incrementable<>
- > requirements;
- //[references5
- /*`
- This only applies when a reference is constructed
- from a value. If a reference is constructed from another
- reference, the new reference does not depend on the old one.
- */
- any<requirements> x(10);
- boost::shared_ptr<any<requirements, _self&> > p(
- new any<requirements, _self&>(x));
- any<requirements, _self&> y(*p); // equivalent to y(x);
- p.reset();
- ++y; // okay
- //]
- }
- void references6() {
- //[references6
- /*`
- Both const and non-const references are supported.
- */
- int i = 0;
- any<incrementable<>, _self&> x(i);
- any<incrementable<>, const _self&> y(x);
- /*`
- A reference to non-const can be converted to a reference
- to const, but not the other way around. Naturally,
- we can't apply mutating operations to a const reference.
- any<incrementable<>, _self&> z(y); // error
- ++y; // error
- */
- //]
- }
- //[references
- //` (For the source of the examples in this section see
- //` [@boost:/libs/type_erasure/example/references.cpp references.cpp])
- //` [references1]
- //` [references2]
- //` [references3]
- //` [references4]
- //` [references5]
- //` [references6]
- //]
|