]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/type_erasure/example/basic.cpp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / libs / type_erasure / example / basic.cpp
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/type_erasure/member.hpp>
16 #include <boost/type_erasure/free.hpp>
17 #include <boost/mpl/vector.hpp>
18 #include <iostream>
19 #include <vector>
20
21 namespace mpl = boost::mpl;
22 using namespace boost::type_erasure;
23
24 void basic1() {
25 //[basic1
26 /*`
27 The main class in the library is __any. An __any can
28 store objects that meet whatever requirements we specify.
29 These requirements are passed to __any as an MPL sequence.
30
31 [note The MPL sequence combines multiple concepts.
32 In the rare case when we only want a single concept, it doesn't
33 need to be wrapped in an MPL sequence.]
34 */
35 any<mpl::vector<copy_constructible<>, typeid_<>, relaxed> > x(10);
36 int i = any_cast<int>(x); // i == 10
37 /*`
38 __copy_constructible is a builtin concept that allows us to
39 copy and destroy the object. __typeid_ provides run-time
40 type information so that we can use __any_cast. __relaxed
41 enables various useful defaults. Without __relaxed,
42 __any supports /exactly/ what you specify and nothing else.
43 In particular, it allows default construction and assignment of __any.
44 */
45 //]
46 }
47
48 void basic2() {
49 //[basic2
50 /*`
51 Now, this example doesn't do very much. `x` is approximately
52 equivalent to a [@boost:/libs/any/index.html boost::any].
53 We can make it more interesting by adding some operators,
54 such as `operator++` and `operator<<`.
55 */
56 any<
57 mpl::vector<
58 copy_constructible<>,
59 typeid_<>,
60 incrementable<>,
61 ostreamable<>
62 >
63 > x(10);
64 ++x;
65 std::cout << x << std::endl; // prints 11
66 //]
67 }
68
69 //[basic3
70 /*`
71 The library provides concepts for most C++ operators, but this
72 obviously won't cover all use cases; we often need to
73 define our own requirements. Let's take the `push_back`
74 member, defined by several STL containers.
75 */
76
77 BOOST_TYPE_ERASURE_MEMBER(push_back)
78
79 void append_many(any<has_push_back<void(int)>, _self&> container) {
80 for(int i = 0; i < 10; ++i)
81 container.push_back(i);
82 }
83
84 /*`
85 We use the macro __BOOST_TYPE_ERASURE_MEMBER
86 to define a concept called `has_push_back`.
87 When we use `has_push_back`, we have to
88 tell it the signature of the function, `void(int)`.
89 This means that the type we store in the any
90 has to have a member that looks like:
91
92 ``
93 void push_back(int);
94 ``
95
96 Thus, we could call `append_many` with `std::vector<int>`,
97 `std::list<int>`, or `std::vector<long>` (because `int` is
98 convertible to `long`), but not `std::list<std::string>`
99 or `std::set<int>`.
100
101 Also, note that `append_many` has to operate directly
102 on its argument. It cannot make a copy. To handle this
103 we use `_self&` as the second argument of __any. `_self`
104 is a __placeholder. By using `_self&`, we indicate that
105 the __any stores a reference to an external object instead of
106 allocating its own object.
107 */
108
109 /*`
110 Member functions can be const.
111 */
112 BOOST_TYPE_ERASURE_MEMBER(empty)
113 bool is_empty(any<has_empty<bool() const>, const _self&> x) {
114 return x.empty();
115 }
116
117 /*`
118 For free functions, we can use the macro __BOOST_TYPE_ERASURE_FREE.
119 */
120
121 BOOST_TYPE_ERASURE_FREE(getline)
122 std::vector<std::string> read_lines(any<has_getline<bool(_self&, std::string&)>, _self&> stream)
123 {
124 std::vector<std::string> result;
125 std::string tmp;
126 while(getline(stream, tmp))
127 result.push_back(tmp);
128 return result;
129 }
130
131 /*`
132 The use of `has_getline` is very similar to `has_push_back` above.
133 The difference is that the placeholder `_self` is passed in
134 the function signature instead of as a separate argument.
135
136 The __placeholder doesn't have to be the first argument.
137 We could just as easily make it the second argument.
138 */
139
140
141 void read_line(any<has_getline<bool(std::istream&, _self&)>, _self&> str)
142 {
143 getline(std::cin, str);
144 }
145
146 //]
147
148 //[basic
149 //` (For the source of the examples in this section see
150 //` [@boost:/libs/type_erasure/example/basic.cpp basic.cpp])
151 //` [basic1]
152 //` [basic2]
153 //` [basic3]
154 //]