]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | #ifndef OPENTRACING_UTIL_RECURSIVE_WRAPPER_HPP |
2 | #define OPENTRACING_UTIL_RECURSIVE_WRAPPER_HPP | |
3 | ||
4 | // Based on variant/recursive_wrapper.hpp from boost. | |
5 | // | |
6 | // Original license: | |
7 | // | |
8 | // Copyright (c) 2002-2003 | |
9 | // Eric Friedman, Itay Maman | |
10 | // | |
11 | // Distributed under the Boost Software License, Version 1.0. (See | |
12 | // accompanying file LICENSE_1_0.txt or copy at | |
13 | // http://www.boost.org/LICENSE_1_0.txt) | |
14 | ||
15 | #include <cassert> | |
16 | #include <utility> | |
17 | #include <opentracing/version.h> | |
18 | ||
19 | namespace opentracing { | |
20 | BEGIN_OPENTRACING_ABI_NAMESPACE | |
21 | namespace util { | |
22 | ||
23 | template <typename T> | |
24 | class recursive_wrapper | |
25 | { | |
26 | ||
27 | T* p_; | |
28 | ||
29 | void assign(T const& rhs) | |
30 | { | |
31 | this->get() = rhs; | |
32 | } | |
33 | ||
34 | public: | |
35 | using type = T; | |
36 | ||
37 | /** | |
38 | * Default constructor default initializes the internally stored value. | |
39 | * For POD types this means nothing is done and the storage is | |
40 | * uninitialized. | |
41 | * | |
42 | * @throws std::bad_alloc if there is insufficient memory for an object | |
43 | * of type T. | |
44 | * @throws any exception thrown by the default constructur of T. | |
45 | */ | |
46 | recursive_wrapper() | |
47 | : p_(new T){} | |
48 | ||
49 | ~recursive_wrapper() noexcept { delete p_; } | |
50 | ||
51 | recursive_wrapper(recursive_wrapper const& operand) | |
52 | : p_(new T(operand.get())) {} | |
53 | ||
54 | recursive_wrapper(T const& operand) | |
55 | : p_(new T(operand)) {} | |
56 | ||
57 | recursive_wrapper(recursive_wrapper&& operand) | |
58 | : p_(new T(std::move(operand.get()))) {} | |
59 | ||
60 | recursive_wrapper(T&& operand) | |
61 | : p_(new T(std::move(operand))) {} | |
62 | ||
63 | inline recursive_wrapper& operator=(recursive_wrapper const& rhs) | |
64 | { | |
65 | assign(rhs.get()); | |
66 | return *this; | |
67 | } | |
68 | ||
69 | inline recursive_wrapper& operator=(T const& rhs) | |
70 | { | |
71 | assign(rhs); | |
72 | return *this; | |
73 | } | |
74 | ||
75 | inline void swap(recursive_wrapper& operand) noexcept | |
76 | { | |
77 | T* temp = operand.p_; | |
78 | operand.p_ = p_; | |
79 | p_ = temp; | |
80 | } | |
81 | ||
82 | recursive_wrapper& operator=(recursive_wrapper&& rhs) noexcept | |
83 | { | |
84 | swap(rhs); | |
85 | return *this; | |
86 | } | |
87 | ||
88 | recursive_wrapper& operator=(T&& rhs) | |
89 | { | |
90 | get() = std::move(rhs); | |
91 | return *this; | |
92 | } | |
93 | ||
94 | T& get() | |
95 | { | |
96 | assert(p_); | |
97 | return *get_pointer(); | |
98 | } | |
99 | ||
100 | T const& get() const | |
101 | { | |
102 | assert(p_); | |
103 | return *get_pointer(); | |
104 | } | |
105 | ||
106 | T* get_pointer() { return p_; } | |
107 | ||
108 | const T* get_pointer() const { return p_; } | |
109 | ||
110 | operator T const&() const { return this->get(); } | |
111 | ||
112 | operator T&() { return this->get(); } | |
113 | ||
114 | }; // class recursive_wrapper | |
115 | ||
116 | template <typename T> | |
117 | inline void swap(recursive_wrapper<T>& lhs, recursive_wrapper<T>& rhs) noexcept | |
118 | { | |
119 | lhs.swap(rhs); | |
120 | } | |
121 | } // namespace util | |
122 | END_OPENTRACING_ABI_NAMESPACE | |
123 | } // namespace opentracing | |
124 | ||
125 | #endif // OPENTRACING_UTIL_RECURSIVE_WRAPPER_HPP |