Simulant  21.09-46
A portable game engine for Windows, OSX, Linux, Dreamcast, and PSP
property.h
1 /* * Copyright (c) 2011-2017 Luke Benstead https://simulant-engine.appspot.com
2  *
3  * This file is part of Simulant.
4  *
5  * Simulant is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * Simulant is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with Simulant. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #pragma once
20 
21 #include <type_traits>
22 #include <functional>
23 #include <memory>
24 #include <cstdint>
25 
26 #include "default_init_ptr.h"
27 
28 namespace smlt {
29 
30 namespace property_impl {
31 
32 template<typename MP, typename C, typename T>
33 struct Getter;
34 
35 template<typename MP, typename C, typename T>
36 struct Getter<MP, C, std::weak_ptr<T>> {
37  MP mp_;
38 
39  Getter(MP mp):
40  mp_(mp) {
41 
42  }
43 
44  T* get(C* _this) const {
45  if(auto sptr = (_this->*mp_).lock()) {
46  return sptr.get();
47  } else {
48  return nullptr;
49  }
50  }
51 };
52 
53 template<typename MP, typename C, typename T>
54 struct Getter<MP, C, std::shared_ptr<T>> {
55  MP mp_;
56 
57  Getter(MP mp):
58  mp_(mp) {
59 
60  }
61 
62  T* get(C* _this) const {
63  return (_this->*mp_).get();
64  }
65 };
66 
67 template<typename MP, typename C, typename T>
68 struct Getter<MP, C, std::unique_ptr<T>> {
69  MP mp_;
70 
71  Getter(MP mp):
72  mp_(mp) {
73 
74  }
75 
76  T* get(C* _this) const {
77  return (_this->*mp_).get();
78  }
79 };
80 
81 template<typename MP, typename C, typename T>
82 struct Getter<MP, C, default_init_ptr<T>> {
83  MP mp_;
84 
85  Getter(MP mp):
86  mp_(mp) {
87 
88  }
89 
90  T* get(C* _this) const {
91  return (_this->*mp_);
92  }
93 };
94 
95 template<typename MP, typename C, typename T>
96 struct Getter<MP, C, T*> {
97  static_assert(!std::is_function<MP>::value, "MP was a function");
98 
99  MP mp_;
100 
101  Getter(MP mp):
102  mp_(mp) {
103 
104  }
105 
106  T* get(C* _this) const {
107  return (_this->*mp_);
108  }
109 };
110 
111 
112 template<typename MP, typename C, typename T>
113 struct Getter<MP, C, T* () const> {
114  MP mp_;
115 
116  Getter(MP mp):
117  mp_(mp) {
118 
119  }
120 
121  T* get(C* _this) const {
122  return (_this->*mp_)();
123  }
124 };
125 
126 template<typename MP, typename C, typename T>
127 struct Getter {
128  MP mp_;
129 
130  static_assert(!std::is_pointer<T>::value, "T was a pointer");
131  static_assert(!std::is_function<T>::value, "T was a function");
132 
133  Getter(MP mp):
134  mp_(mp) {
135 
136  }
137 
138  T* get(C* _this) const {
139  return &(_this->*mp_);
140  }
141 };
142 
143 }
144 
145 template<typename T>
146 struct ExtractType {
147  static_assert(!std::is_function<T>::value, "T was a function");
148 
149  typedef T type;
150 };
151 
152 template<typename T>
153 struct ExtractType<T*> {
154  typedef typename std::remove_pointer<T>::type type;
155 };
156 
157 template<typename T>
158 struct ExtractType<std::weak_ptr<T>> {
159  typedef T type;
160 };
161 
162 template<typename T>
163 struct ExtractType<std::shared_ptr<T>> {
164  typedef T type;
165 };
166 
167 template<typename T>
168 struct ExtractType<std::unique_ptr<T>> {
169  typedef T type;
170 };
171 
172 template<typename T>
174  typedef T type;
175 };
176 
177 template<typename T>
178 struct ExtractType<T() const> {
179  typedef typename std::remove_pointer<T>::type type;
180 };
181 
182 
183 template<typename MP>
185 
186 
187 template<typename T, typename U>
188 struct PointerToMemberHelper<T U::*> {
189  typedef U class_type; /* Class */
190  typedef T variable_type; /* The source type */
191 
192  /* This is the underlying type, which needs extracting */
193  typedef typename ExtractType<
194  T
195  >::type result_type;
196 };
197 
198 template<typename MP>
199 struct PointerToMember : PointerToMemberHelper<typename std::remove_cv<MP>::type> {};
200 
201 template<typename MP>
202 class Property {
203 public:
204  typedef typename PointerToMember<MP>::class_type class_type;
205  typedef typename PointerToMember<MP>::variable_type variable_type;
206  typedef typename PointerToMember<MP>::result_type T;
207 
208  Property(class_type* _this, MP member):
209  this_(_this),
210  getter_(member) {}
211 
212  Property() = delete;
213  Property(const Property&) = delete;
214  Property& operator=(const Property& rhs) {
215  assert(this_); /* We don't copy this */
216  getter_ = rhs.getter_;
217  }
218 
219 private:
220  class_type* this_;
222 
223 public:
224 
225  inline operator T&() const {
226  return *get();
227  }
228 
229  inline T* operator->() const {
230  return get();
231  }
232 
233  inline operator T*() {
234  return get();
235  }
236 
237  T* get() const {
238  return getter_.get(this_);
239  }
240 
241  operator bool() const { return bool(get(this));}
242 };
243 
244 }
245 
246 #define S_DEFINE_PROPERTY(name, member) \
247  Property<decltype(member)> name = {this, member}
smlt::Property
Definition: property.h:202
smlt::PointerToMemberHelper
Definition: property.h:184
smlt::PointerToMember
Definition: property.h:199
smlt
Definition: animation.cpp:25
smlt::property_impl::Getter
Definition: property.h:127
smlt::ExtractType
Definition: property.h:146
std
Extensions to the C++ standard library.
Definition: unique_id.h:200
smlt::default_init_ptr
Definition: default_init_ptr.h:8