neoGFX
Cross-platform C++ app/game engine
Loading...
Searching...
No Matches
any_ref.hpp
Go to the documentation of this file.
1// any_ref.hpp
2/*
3 * Copyright (c) 2007 Leigh Johnston.
4 *
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * * Neither the name of Leigh Johnston nor the names of any
19 * other contributors to this software may be used to endorse or
20 * promote products derived from this software without specific prior
21 * written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*/
35
36#pragma once
37
38#include <neolib/neolib.hpp>
39#include <stdexcept>
40#include <typeinfo>
41
42namespace neolib
43{
44 struct any_const_ref_bad_cast : public std::logic_error
45 {
46 any_const_ref_bad_cast() : std::logic_error("neolib::any_const_ref_bad_cast")
47 {
48 }
49 };
50
52 {
53 // construction
54 public:
55 virtual ~any_const_ref_holder_base() = default;
56 // operations
57 public:
58 template <typename T>
59 operator const T&() const
60 {
61 if (typeid(T) != type())
63 return *static_cast<const T*>(ptr());
64 }
65 template <typename T>
66 bool is() const { return typeid(T) == type(); }
67 virtual any_const_ref_holder_base* clone(void* aWhere) const = 0;
68 // implementation
69 private:
70 virtual const std::type_info& type() const = 0;
71 virtual const void* ptr() const = 0;
72 };
73
74 template <typename T>
76 {
77 // construction
78 public:
79 any_const_ref_holder(const T& aRef) : iRef(aRef) {}
80 // implementation
81 private:
82 virtual any_const_ref_holder_base* clone(void* aWhere) const { return new (aWhere) any_const_ref_holder(iRef); }
83 virtual const std::type_info& type() const { return typeid(T); }
84 virtual const void* ptr() const { return &iRef; }
85 // attributes
86 private:
87 const T& iRef;
88 };
89
90 struct any_ref_bad_cast : public std::logic_error
91 {
92 any_ref_bad_cast() : std::logic_error("neolib::any_ref_bad_cast")
93 {
94 }
95 };
96
98 {
99 // construction
100 public:
101 virtual ~any_ref_holder_base() = default;
102 // operations
103 public:
104 template <typename T>
105 operator T&() const
106 {
107 if (typeid(T) != type())
108 throw any_ref_bad_cast();
109 return *static_cast<T*>(ptr());
110 }
111 template <typename T>
112 bool is() const { return typeid(T) == type(); }
113 virtual any_ref_holder_base* clone(void* aWhere) const = 0;
114 virtual any_const_ref_holder_base* const_clone(void* aWhere) const = 0;
115 // implementation
116 private:
117 virtual const std::type_info& type() const = 0;
118 virtual void* ptr() const = 0;
119 };
120
121 template <typename T>
123 {
124 // construction
125 public:
126 any_ref_holder(T& aRef) : iRef(aRef) {}
127 // implementation
128 private:
129 virtual any_ref_holder_base* clone(void* aWhere) const { return new (aWhere) any_ref_holder(iRef); }
130 virtual any_const_ref_holder_base* const_clone(void* aWhere) const { return new (aWhere) any_const_ref_holder<T>(const_cast<const T&>(iRef)); }
131 virtual const std::type_info& type() const { return typeid(T); }
132 virtual void* ptr() const { return &iRef; }
133 // attributes
134 private:
135 T& iRef;
136 };
137
139 {
140 friend class any_const_ref;
141 // construction
142 public:
143 any_ref() : iHolder(nullptr) {}
144 template <typename T>
145 any_ref(T& aObject) : iHolder(new (iSpace.iBytes) any_ref_holder<T>(aObject)) {}
146 any_ref(const any_ref& aOther) : iHolder(aOther.iHolder ? aOther.iHolder->clone(iSpace.iBytes) : nullptr) {}
147 any_ref(any_ref& aOther) : iHolder(aOther.iHolder ? aOther.iHolder->clone(iSpace.iBytes) : nullptr) {}
148 ~any_ref() { destroy(); }
149 any_ref& operator=(const any_ref& aOther)
150 {
151 destroy();
152 if (aOther.iHolder)
153 iHolder = aOther.iHolder->clone(iSpace.iBytes);
154 return *this;
155 }
156 // operations
157 public:
158 template <typename T>
159 operator T&() const { if (empty()) throw any_ref_bad_cast(); return *iHolder; }
160 template <typename T>
161 bool is() const { return iHolder && iHolder->is<T>(); }
162 bool something() const { return iHolder != nullptr; }
163 bool empty() const { return !something(); }
164 void reset() { destroy(); }
165 // implementation
166 private:
167 void destroy() { if (iHolder != nullptr) iHolder->~any_ref_holder_base(); iHolder = nullptr; }
168 // attributes
169 private:
170 union
171 {
172 std::max_align_t alignTo;
174 } iSpace;
175 any_ref_holder_base* iHolder;
176 };
177
179 {
180 // construction
181 public:
182 any_const_ref() : iHolder(nullptr) {}
183 template <typename T>
184 any_const_ref(const T& aObject) : iHolder(new (iSpace.iBytes) any_const_ref_holder<T>(aObject)) {}
185 any_const_ref(const any_ref& aOther) : iHolder(aOther.iHolder ? aOther.iHolder->const_clone(iSpace.iBytes) : nullptr) {}
186 any_const_ref(const any_const_ref& aOther) : iHolder(aOther.iHolder ? aOther.iHolder->clone(iSpace.iBytes) : nullptr) {}
187 any_const_ref(any_const_ref& aOther) : iHolder(aOther.iHolder ? aOther.iHolder->clone(iSpace.iBytes) : nullptr) {}
188 ~any_const_ref() { destroy(); }
190 {
191 destroy();
192 if (aOther.iHolder)
193 iHolder = aOther.iHolder->clone(iSpace.iBytes);
194 return *this;
195 }
196 // operations
197 public:
198 template <typename T>
199 operator const T&() const { if (empty()) throw any_const_ref_bad_cast(); return *iHolder; }
200 template <typename T>
201 bool is() const { return iHolder && iHolder->is<T>(); }
202 bool something() const { return iHolder != nullptr; }
203 bool empty() const { return !something(); }
204 void reset() { destroy(); }
205 // implementation
206 private:
207 void destroy() { if (iHolder != nullptr) iHolder->~any_const_ref_holder_base(); iHolder = nullptr; }
208 // attributes
209 private:
210 union
211 {
212 std::max_align_t alignTo;
214 } iSpace;
216 };
217}
virtual ~any_const_ref_holder_base()=default
virtual any_const_ref_holder_base * clone(void *aWhere) const =0
any_const_ref_holder(const T &aRef)
Definition any_ref.hpp:79
bool something() const
Definition any_ref.hpp:202
any_const_ref(const any_ref &aOther)
Definition any_ref.hpp:185
any_const_ref(const any_const_ref &aOther)
Definition any_ref.hpp:186
std::max_align_t alignTo
Definition any_ref.hpp:212
any_const_ref(const T &aObject)
Definition any_ref.hpp:184
any_const_ref & operator=(const any_const_ref &aOther)
Definition any_ref.hpp:189
bool empty() const
Definition any_ref.hpp:203
char iBytes[sizeof(any_const_ref_holder< char >)]
Definition any_ref.hpp:213
any_const_ref(any_const_ref &aOther)
Definition any_ref.hpp:187
virtual any_const_ref_holder_base * const_clone(void *aWhere) const =0
virtual ~any_ref_holder_base()=default
virtual any_ref_holder_base * clone(void *aWhere) const =0
any_ref(const any_ref &aOther)
Definition any_ref.hpp:146
any_ref(T &aObject)
Definition any_ref.hpp:145
any_ref & operator=(const any_ref &aOther)
Definition any_ref.hpp:149
bool is() const
Definition any_ref.hpp:161
char iBytes[sizeof(any_ref_holder< char >)]
Definition any_ref.hpp:173
bool empty() const
Definition any_ref.hpp:163
bool something() const
Definition any_ref.hpp:162
std::max_align_t alignTo
Definition any_ref.hpp:172
any_ref(any_ref &aOther)
Definition any_ref.hpp:147
Definition plf_hive.h:79