All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Macros Pages
components_example.cpp
Go to the documentation of this file.
1 //=======================================================================
2 // Copyright (c) 2013 Piotr Wygocki
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See
5 // accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 //=======================================================================
18 
19 #include <type_traits>
20 #include <functional>
21 #include <cassert>
22 
23 // this are names for components used in all of the examples
24 namespace names {
25 struct A;
26 struct B;
27 struct C;
28 }
29 
30 namespace ds = paal::data_structures;
31 
32 // definition of Comps with names names::A, names::B, names::C
33 template <typename... Args>
34 using Comps =
36 
37 void example_default_constructor_and_basic_usage() {
38  // constructor has default agruments
39  typedef Comps<int, double, int> MyComps;
40  MyComps comps;
41  // getter
42  assert(comps.get<names::A>() == 0); // zero initialization is guaranteed
43 
44  // setter
45  comps.set<names::C>(7);
46  assert(comps.get<names::C>() == 7);
47 
48  const MyComps &constAlias = comps;
49  // const version of get
50  constAlias.get<names::B>();
51 }
52 
53 void example_constructor_with_all_arguments() {
54  // constructor with parameters
55  Comps<int, double, int> comps(5, 4, 3);
56  assert(comps.get<names::A>() == 5);
57  assert(comps.get<names::B>() == 4);
58  assert(comps.get<names::C>() == 3);
59 }
60 
61 void example_constructor_with_some_arguments() {
62  // default value for 3rd argument
63  Comps<int, double, int> comps(5, 4);
64  assert(comps.get<names::A>() == 5);
65  assert(comps.get<names::B>() == 4);
66 }
67 
68 int f(int i) { return i; }
69 void example_calling_function_from_components() {
70  // declaration components with function
71  typedef Comps<int (*)(int), int (*)(int), int> CompsF;
72 
73  // definition
74  CompsF comps(f, f, 17);
75  const CompsF &constAlias = comps;
76 
77  // call the first argument
78  assert(comps.call<names::A>(2) == 2);
79 
80  // const version
81  assert(constAlias.call<names::B>(2) == 2);
82 }
83 
84 void example_replacing() {
85  // components with replaceped type
86  typedef Comps<int (*)(int), double, int> CompsF;
87 
89  Replaced;
90  typedef Comps<std::pair<int, int>, double, int> ReplacedCheck;
91  static_assert(std::is_same<Replaced, ReplacedCheck>::value,
92  "Invalid replaceped type");
93 
94  // replace components
95  CompsF comps(f, 2, 17);
96  Replaced replaced = ds::replace<names::A>(std::make_pair(11, 12), comps);
97 
98  auto p = replaced.get<names::A>();
99  assert(p.first == 11);
100  assert(p.second == 12);
101  assert(replaced.get<names::B>() == 2);
102  assert(replaced.get<names::C>() == 17);
103 }
104 
105 // this three function are not default constructible
106 // this is to show that this is not needed if not explicyty used
107 struct X {
108  explicit X(int _x) : x(_x) {}
109  X() = delete;
110  bool operator==(X xx) const { return x == xx.x; }
111 
112  int x;
113 };
114 
115 struct Y {
116  explicit Y(int _y) : y(_y) {}
117  Y() = delete;
118 
119  int y;
120 };
121 
122 struct Z {
123  explicit Z(int _z) : z(_z) {}
124  Z() = delete;
125 
126  int z;
127 };
128 
129 // comnponts with defaults
130 template <typename... Args>
131 using CompsWithDefaults = typename ds::components<
132  names::A, names::B, ds::NameWithDefault<names::C, X>>::type<Args...>;
133 
134 void example_default_parameters() {
135  // normal definition
136  CompsWithDefaults<int, double, float> compsDef;
137 
138  // definition with default 3rd template parameter
139  CompsWithDefaults<int, double> compsDef2(1, 2, 3);
140  assert(compsDef2.get<names::C>() == X(3));
141 
142  // This won't compile
143  // CompsWithDefaults<int> comps3;
144 }
145 
146 // definition of Comps with names names::A, names::B
147 template <typename... Args>
148 using CompsToReplace =
150 
151 void example_replacing_struct_without_default_constructors() {
152  X x(1);
153  Y y(2);
154  Z z(3);
155 
156  CompsToReplace<X, Y> compsToReplace(x, y);
157  // replace, X, Y, Z doesn't have default constructors
158  auto s = ds::replace<names::A>(z, compsToReplace);
159  assert(s.get<names::A>().z == 3);
160 
161  auto s2 = ds::replace<names::B>(z, compsToReplace);
162  assert(s2.get<names::B>().z == 3);
163 }
164 
165 void example_create_using_make() {
166  // constructing objects providing names for objects
167  typedef Comps<int, double, float> SomeComps;
168  auto someComps = SomeComps::make<names::A, names::C>(1, 2.f);
169  assert(someComps.get<names::A>() == 1);
170  assert(someComps.get<names::C>() == 2.f);
171 
172  auto someComps2 = SomeComps::make<names::C, names::A>(1.f, 2);
173  assert(someComps2.get<names::C>() == 1.f);
174  assert(someComps2.get<names::A>() == 2);
175 }
176 
177 void example_create_using_copy_tag() {
178  typedef Comps<int, double, float> SomeComps;
179  SomeComps someComps(CompsToReplace<int, int>(1, 2), ds::copy_tag());
180  assert(someComps.get<names::A>() == 1);
181  assert(someComps.get<names::B>() == 2.);
182 }
183 
184 void example_references() {
185  // references works also
186  int a;
187  typedef Comps<int, const int &, int &> CompsWithRefs;
188  CompsWithRefs compsWithRefs(a, a, a);
189 
190  CompsWithRefs::make<names::B, names::C>(a, a);
191 }
192 
193 void example_make_components() {
194  // this is the way of constructing components without providing actual types
195  typedef ds::components<names::A, names::B> MComps;
196 
197  int a;
198  auto mComps = MComps::make_components(1, std::ref(a));
199  static_assert(std::is_same<std::remove_reference<decltype(mComps)>::type,
200  MComps::type<int, int &>>::value,
201  "Ups...");
202 }
203 
204 // this shouldn't compile
205 // template <typename... Args>
206 // using CompsWithDefaultsIncorrect = typename ds::components<
207 // names::A, ds::NameWithDefault<names::B, X>, names::C>::type<Args...>;
208 
209 int main() {
210  example_default_constructor_and_basic_usage();
211  example_constructor_with_all_arguments();
212  example_constructor_with_some_arguments();
213  example_calling_function_from_components();
214  example_replacing();
215  example_default_parameters();
216  example_replacing_struct_without_default_constructors();
217  example_create_using_make();
218  example_create_using_copy_tag();
219  example_references();
220  example_make_components();
221 }
This structure can be passed on Names list and represents Name and the default type value...
Definition: components.hpp:33
Indicates that components constructor is in fact a Copy/Move Constructor.
Definition: components.hpp:39
Generic version of replaced_type.