1// Boost.TypeErasure library
2//
3// Copyright 2011 Steven Watanabe
4//
5// Distributed under the Boost Software License Version 1.0. (See
6// accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//
9// $Id$
10
11#include <boost/type_erasure/any.hpp>
12#include <boost/type_erasure/any_cast.hpp>
13#include <boost/type_erasure/builtin.hpp>
14#include <boost/type_erasure/operators.hpp>
15#include <boost/mpl/vector.hpp>
16#include <boost/shared_ptr.hpp>
17#include <iostream>
18
19namespace mpl = boost::mpl;
20using namespace boost::type_erasure;
21
22void references1() {
23 //[references1
24 /*`
25 To capture by reference, we simply add a reference
26 to the __placeholder.
27 */
28 int i;
29 any<typeid_<>, _self&> x(i);
30 any_cast<int&>(arg&: x) = 5; // now i is 5
31 /*`
32 [note `_self` is the default __placeholder, so it is
33 easiest to use `_self&`. We could use another
34 __placeholder instead. __any`<`__typeid_`<_a>, _a&>` has
35 exactly the same behavior.]
36 */
37 //]
38}
39
40void references2() {
41 //[references2
42 /*`
43 References cannot be rebound. Just like a built-in C++ reference,
44 once you've initialized it you can't change it to point to
45 something else.
46 ``
47 int i, j;
48 any<typeid_<>, _self&> x(i), y(j);
49 x = y; // error
50 ``
51
52 [note As with any other operation, `x = y` for references
53 acts on `i` and `j`. Assignment like this is legal
54 if __assignable`<>` is in the Concept, but `x` would
55 still hold a reference to `i`.]
56 */
57 //]
58}
59
60void references3() {
61 //[references3
62 /*`
63 A reference can be bound to another __any.
64 */
65 typedef mpl::vector<
66 copy_constructible<>,
67 incrementable<>
68 > requirements;
69
70 any<requirements> x(10);
71 any<requirements, _self&> y(x);
72 ++y; // x is now 11
73 //]
74}
75
76void references4() {
77 //[references4
78 /*`
79 If a reference is used after the underlying object
80 goes out of scope or is reset, the behavior is undefined.
81 */
82 typedef mpl::vector<
83 copy_constructible<>,
84 incrementable<>,
85 relaxed
86 > requirements;
87 any<requirements> x(10);
88 any<requirements, _self&> y(x);
89 x = 1.0;
90 ++y; // undefined behavior.
91 //]
92}
93
94void references5() {
95 typedef mpl::vector<
96 copy_constructible<>,
97 incrementable<>
98 > requirements;
99 //[references5
100 /*`
101 This only applies when a reference is constructed
102 from a value. If a reference is constructed from another
103 reference, the new reference does not depend on the old one.
104 */
105 any<requirements> x(10);
106 boost::shared_ptr<any<requirements, _self&> > p(
107 new any<requirements, _self&>(x));
108 any<requirements, _self&> y(*p); // equivalent to y(x);
109 p.reset();
110 ++y; // okay
111 //]
112}
113
114void references6() {
115 //[references6
116 /*`
117 Both const and non-const references are supported.
118 */
119 int i = 0;
120 any<incrementable<>, _self&> x(i);
121 any<incrementable<>, const _self&> y(x);
122 /*`
123 A reference to non-const can be converted to a reference
124 to const, but not the other way around. Naturally,
125 we can't apply mutating operations to a const reference.
126
127 any<incrementable<>, _self&> z(y); // error
128 ++y; // error
129 */
130 //]
131}
132
133//[references
134//` (For the source of the examples in this section see
135//` [@boost:/libs/type_erasure/example/references.cpp references.cpp])
136//` [references1]
137//` [references2]
138//` [references3]
139//` [references4]
140//` [references5]
141//` [references6]
142//]
143

source code of boost/libs/type_erasure/example/references.cpp