KisaragiLibrary
 
読み取り中…
検索中…
一致する文字列を見つけられません
Accessor.hpp
[詳解]
1#pragma once
2
3
4#include <functional>
5#include <type_traits>
6#include <utility>
7
8//TODO Accessor
9//・インクリメント/デクリメント対応
10//・ReadOnlyに関数を使えるvarの追加or変更
11
12
13
14/*
15* CustomAccessorの使い方
16*
17* CustomAccessorとCustomWriteOnlyは自分でセッタを定義できますが、
18* その代わりにコンストラクタで関数を渡す必要があります。
19* 以下はその一例になります。
20*/
21
22/*
23* 1. メンバ以外の関数または、静的なメンバ関数を渡す
24* int test (int _set)
25* {
26* int tmp = _set;
27* if(tmp > 10){ tmp = 10; }
28* return tmp;
29* }
30* int aa = 10;
31* CustomWriteOnly<int> bb(&aa, test);
32*/
33
34/*
35* 2.メンバ関数を渡す
36* class hoge
37* {
38* private:
39* double Func(double _set);
40* double aa;
41* public:
42* CustomWriteOnly<double> bb(&aa, [this](double _set){ Func(_set); } );
43* }
44*/
45
46/*
47* 3.ラムダ式を渡す
48* CustomWriteOnly<float> bb(&aa, [](float _set){ return _set + 10; } );
49*/
50
51
52
53namespace
54{
55 using std::function;
56
57 // declval オブジェクトを生成しないで型を評価する
58 // decltype 引数の結果が有効なら結果の型を返す。有効ならvoid_tが起動する
59 // void_t 引数が有効ならならvoidを返す 失敗ならエラーが発生。
60 // SFINAE は、テンプレートの特殊化が失敗した場合にコンパイルエラーを発生させず、
61 // 代わりに他のテンプレートを選択できるようにします
62 // 成功した場合は trueを継承 失敗ならば他tmplateの falseを継承 したobjになる。
63
64 // 演算子+ はstd::内に使えるのがあったので省略
65
66#pragma region - 演算子用
67 // 演算子-が使えない場合はこちらが使われる
68 template <typename T, typename = void>
69 struct if_subtraction : std::false_type {};
70
71 // 演算子-が使える場合こちらになる
72 template <typename T>
73 struct if_subtraction<T, std::void_t<decltype(std::declval<T>() - std::declval<T>())>> : std::true_type {};
74#pragma endregion
75
76#pragma region * 演算子用
77 // 演算子-が使えない場合はこちらが使われる
78 template <typename T, typename = void>
79 struct if_multiplication : std::false_type {};
80
81 // 演算子-が使える場合こちらになる
82 template <typename T>
83 struct if_multiplication<T, std::void_t<decltype(std::declval<T>()* std::declval<T>())>> : std::true_type {};
84#pragma endregion
85
86#pragma region / 演算子用
87 // 演算子-が使えない場合はこちらが使われる
88 template <typename T, typename = void>
89 struct if_division : std::false_type {};
90
91 // 演算子-が使える場合こちらになる
92 template <typename T>
93 struct if_division<T, std::void_t<decltype(std::declval<T>() / std::declval<T>())>> : std::true_type {};
94#pragma endregion
95
96#pragma region % 演算子用
97 // 演算子-が使えない場合はこちらが使われる
98 template <typename T, typename = void>
99 struct if_remainder : std::false_type {};
100
101 // 演算子-が使える場合こちらになる
102 template <typename T>
103 struct if_remainder<T, std::void_t<decltype(std::declval<T>() % std::declval<T>())>> : std::true_type {};
104#pragma endregion
105
106
107}
108
110{
111 /// <summary>
112 /// public空間に置くことで,T*のSetterを提供します
113 /// </summary>
114 /// <typeparam name="T">Setterの型</typeparam>
115 template <class T>
116 class ReadOnly
117 {
118 protected:
119 T* variable; // 基底クラスの変数をスコープに持ち込む
120
121 public:
122 ReadOnly(T* _variable)
123 {
124 variable = _variable;
125 }
126
127#pragma region Getter
128 //Getter
129 operator T() const
130 {
131 return *variable;
132 }
133
134 //メンバ選択演算子
135 const T* operator->() const
136 {
137 return variable;
138 }
139#pragma endregion
140
141 //TODO インクリメント2種 デクリメント2種
142#pragma region 算術演算子
143 //enabele_ifの引数がfalseならコンパイルされない、詳しくはSFINAE
144
145 //算術型 + がオーバーロードされている型なら
146 //typename std::enable_if<条件,戻り値の型>::type
147 template<typename U = T> //明示的にtemplateであることを宣言しないとエラーが発生しました。
148 typename std::enable_if<std::is_arithmetic<U>::value, U>::type
149 operator +(U _plus) const
150 {
151 return *variable + _plus;
152 }
153
154 //ロジックはif_subtractionを参照
155 template<typename U = T> //明示的にtemplateであることを宣言しないとエラーが発生しました。
156 typename std::enable_if<if_subtraction<U>::value, U>::type
157 operator -(U _index) const
158 {
159 return *variable - _index;
160 }
161
162 template<typename U = T>
163 typename std::enable_if<if_multiplication<U>::value, U>::type
164 operator *(U _index) const
165 {
166 return *variable * _index;
167 }
168
169 template<typename U = T>
170 typename std::enable_if<if_division<U>::value, U>::type
171 operator /(U _index) const
172 {
173 return *variable / _index;
174 }
175
176 template<typename U = T>
177 typename std::enable_if<if_remainder<U>::value, U>::type
178 operator %(U _index) const
179 {
180 return *variable % _index;
181 }
182
183#pragma endregion
184
185
186
187 };
188
189 /// <summary>
190 /// public空間に置くことで,T*のGetterを提供します
191 /// </summary>
192 /// <typeparam name="T">Getterの型</typeparam>
193 template <class T>
195 {
196 protected:
197 T* variable; // 基底クラスの変数をスコープに持ち込む
198
199 public:
200 WriteOnly(T* _variable)
201 {
202 variable = _variable;
203 }
204
205#pragma region Setter
206 //Setter
207 void operator = (T _set)
208 {
209 *variable = _set;
210 }
211
212 //TODO 要素のGetは可能になる
213 //要素の変更を許す
215 {
216 return variable ;
217 }
218#pragma endregion
219
220
221#pragma region 算術 =
222 template<typename U = T>
223 typename std::enable_if<std::is_arithmetic<U>::value, void>::type
224 operator += (T _index)
225 {
226 *this = *variable + _index;
227 }
228
229 template<typename U = T> //明示的にtemplateであることを宣言しないとエラーが発生しました。
230 typename std::enable_if<if_subtraction<U>::value, void>::type
231 operator -=(U _index)
232 {
233 *this = *variable - _index;
234 }
235
236 template<typename U = T>
237 typename std::enable_if<if_multiplication<U>::value, void>::type
238 operator *=(U _index)
239 {
240 *this = *variable * _index;
241 }
242
243 template<typename U = T>
244 typename std::enable_if<if_division<U>::value, void>::type
245 operator /=(U _index)
246 {
247 *this = *variable / _index;
248 }
249
250 template<typename U = T>
251 typename std::enable_if<if_remainder<U>::value, void>::type
252 operator %=(U _index)
253 {
254 *this = *variable % _index;
255 }
256#pragma endregion
257
258
259 };
260
261 /// <summary>
262 /// public空間に置くことで,T*のAccessorを提供します
263 /// </summary>
264 /// <typeparam name="T">Accessorの型</typeparam>
265 template<class T>
266 class Accessor
267 {
268 protected:
271
272 public:
273 Accessor(T* _variable) : readOnly(_variable),writeOnly(_variable){}
274
275#pragma region 要素アクセス子
277 {
278 return writeOnly.operator->();
279 }
280#pragma endregion
281
282#pragma region Getter
283 //Getter
284 operator T() const
285 {
286 //多分暗黙的に変換されるはず...
287 return readOnly.operator T();
288 }
289#pragma endregion
290
291 //TODO インクリメント2種 デクリメント2種
292#pragma region 算術演算子
293 //enabele_ifの引数がfalseならコンパイルされない、詳しくはSFINAE
294
295 //算術型 + がオーバーロードされている型なら
296 //typename std::enable_if<条件,戻り値の型>::type
297 template<typename U = T> //明示的にtemplateであることを宣言しないとエラーが発生しました。
298 typename std::enable_if<std::is_arithmetic<U>::value, U>::type
299 operator +(U _plus) const
300 {
301 return readOnly.operator+(_plus);
302 }
303
304 //ロジックはif_subtractionを参照
305 template<typename U = T> //明示的にtemplateであることを宣言しないとエラーが発生しました。
306 typename std::enable_if<if_subtraction<U>::value, U>::type
307 operator -(U _index) const
308 {
309 return readOnly.operator- (_index);
310 }
311
312 template<typename U = T>
313 typename std::enable_if<if_multiplication<U>::value, U>::type
314 operator *(U _index) const
315 {
316 return readOnly.operator* (_index);
317 }
318
319 template<typename U = T>
320 typename std::enable_if<if_division<U>::value, U>::type
321 operator /(U _index) const
322 {
323 return readOnly.operator/ (_index);
324 }
325
326 template<typename U = T>
327 typename std::enable_if<if_remainder<U>::value, U>::type
328 operator %(U _index) const
329 {
330 return readOnly.operator% (_index);
331 }
332
333#pragma endregion
334
335#pragma region Setter
336 //Setter
337 void operator = (T _set)
338 {
339 writeOnly.operator= (_set);
340 }
341#pragma endregion
342
343
344#pragma region 算術 =
345 template<typename U = T>
346 typename std::enable_if<std::is_arithmetic<U>::value, void>::type
347 operator += (T _index)
348 {
349 writeOnly.operator+= (_index);
350 }
351
352 template<typename U = T> //明示的にtemplateであることを宣言しないとエラーが発生しました。
353 typename std::enable_if<if_subtraction<U>::value, void>::type
354 operator -=(U _index)
355 {
356 writeOnly.operator-= (_index);
357 }
358
359 template<typename U = T>
360 typename std::enable_if<if_multiplication<U>::value, void>::type
361 operator *=(U _index)
362 {
363 writeOnly.operator*= (_index);
364 }
365
366 template<typename U = T>
367 typename std::enable_if<if_division<U>::value, void>::type
368 operator /=(U _index)
369 {
370 writeOnly.operator/= (_index);
371 }
372
373 template<typename U = T>
374 typename std::enable_if<if_remainder<U>::value, void>::type
375 operator %=(U _index)
376 {
377 writeOnly.operator%= (_index);
378 }
379#pragma endregion
380
381 };
382
383 /// <summary>
384 /// public空間に置くことで,自らが定義したT*のSetterを提供します
385 /// </summary>
386 /// <typeparam name="T">Setterの型</typeparam>
387 template <class T>
389 {
390 private:
392 function<T(T)> SetFunc;
393 public:
394 /// <summary>
395 /// コンストラクタ
396 /// </summary>
397 /// <param name="_variable">Accessorがほしい変数</param>
398 /// <param name="_setFunc">セッタの代入の代わりに行う関数</param>
399 CustomWriteOnly(T* _variable, function<T(T)> _setFunc) : variable(_variable)
400 {
401 SetFunc = _setFunc;
402 }
403
404 void operator = (T _set)
405 {
406 *variable = SetFunc(_set);
407 }
408
409
410 //TODO 要素のGetは可能になる
411 //要素の変更を許す
413 {
414 return variable;
415 }
416
417
418#pragma region 算術 =
419 template<typename U = T>
420 typename std::enable_if<std::is_arithmetic<U>::value, void>::type
421 operator += (T _index)
422 {
423 *this = *variable + _index;
424 }
425
426 template<typename U = T> //明示的にtemplateであることを宣言しないとエラーが発生しました。
427 typename std::enable_if<if_subtraction<U>::value, void>::type
428 operator -=(U _index)
429 {
430 *this = *variable - _index;
431 }
432
433 template<typename U = T>
434 typename std::enable_if<if_multiplication<U>::value, void>::type
435 operator *=(U _index)
436 {
437 *this = *variable * _index;
438 }
439
440 template<typename U = T>
441 typename std::enable_if<if_division<U>::value, void>::type
442 operator /=(U _index)
443 {
444 *this = *variable / _index;
445 }
446
447 template<typename U = T>
448 typename std::enable_if<if_remainder<U>::value, void>::type
449 operator %=(U _index)
450 {
451 *this = *variable % _index;
452 }
453#pragma endregion
454 };
455
456 /// <summary>
457 /// public空間に置くことで,T*のAccessorを提供します,
458 /// 自らがSetterを定義します
459 /// </summary>
460 /// <typeparam name="T">Accessorの型</typeparam>
461 template <class T>
463 {
464 private:
465 protected:
468 public:
469 /// <summary>
470 /// コンストラクタ
471 /// </summary>
472 /// <param name="_variable">Accessorがほしい変数</param>
473 /// <param name="_setFunc">セッタの代入の代わりに行う関数</param>
474 CustomAccessor(T* _variable, function<T(T)> _setFunc) : readOnly(_variable), writeOnly(_variable, _setFunc) {}
475
476
477#pragma region 要素アクセス子
479 {
480 return writeOnly.operator->();
481 }
482#pragma endregion
483
484#pragma region Getter
485 //Getter
486 operator T() const
487 {
488 //多分暗黙的に変換されるはず...
489 return readOnly.operator T();
490 }
491#pragma endregion
492
493 //TODO インクリメント2種 デクリメント2種
494#pragma region 算術演算子
495 //enabele_ifの引数がfalseならコンパイルされない、詳しくはSFINAE
496
497 //算術型 + がオーバーロードされている型なら
498 //typename std::enable_if<条件,戻り値の型>::type
499 template<typename U = T> //明示的にtemplateであることを宣言しないとエラーが発生しました。
500 typename std::enable_if<std::is_arithmetic<U>::value, U>::type
501 operator +(U _plus) const
502 {
503 return readOnly.operator+(_plus);
504 }
505
506 //ロジックはif_subtractionを参照
507 template<typename U = T> //明示的にtemplateであることを宣言しないとエラーが発生しました。
508 typename std::enable_if<if_subtraction<U>::value, U>::type
509 operator -(U _index) const
510 {
511 return readOnly.operator- (_index);
512 }
513
514 template<typename U = T>
515 typename std::enable_if<if_multiplication<U>::value, U>::type
516 operator *(U _index) const
517 {
518 return readOnly.operator* (_index);
519 }
520
521 template<typename U = T>
522 typename std::enable_if<if_division<U>::value, U>::type
523 operator /(U _index) const
524 {
525 return readOnly.operator/ (_index);
526 }
527
528 template<typename U = T>
529 typename std::enable_if<if_remainder<U>::value, U>::type
530 operator %(U _index) const
531 {
532 return readOnly.operator% (_index);
533 }
534
535#pragma endregion
536
537#pragma region Setter
538 //Setter
539 void operator = (T _set)
540 {
541 writeOnly.operator= (_set);
542 }
543#pragma endregion
544
545
546#pragma region 算術 =
547 template<typename U = T>
548 typename std::enable_if<std::is_arithmetic<U>::value, void>::type
549 operator += (T _index)
550 {
551 writeOnly.operator+= (_index);
552 }
553
554 template<typename U = T> //明示的にtemplateであることを宣言しないとエラーが発生しました。
555 typename std::enable_if<if_subtraction<U>::value, void>::type
556 operator -=(U _index)
557 {
558 writeOnly.operator-= (_index);
559 }
560
561 template<typename U = T>
562 typename std::enable_if<if_multiplication<U>::value, void>::type
563 operator *=(U _index)
564 {
565 writeOnly.operator*= (_index);
566 }
567
568 template<typename U = T>
569 typename std::enable_if<if_division<U>::value, void>::type
570 operator /=(U _index)
571 {
572 writeOnly.operator/= (_index);
573 }
574
575 template<typename U = T>
576 typename std::enable_if<if_remainder<U>::value, void>::type
577 operator %=(U _index)
578 {
579 writeOnly.operator%= (_index);
580 }
581#pragma endregion
582
583 };
584}
std::enable_if< std::is_arithmetic< U >::value, U >::type operator+(U _plus) const
Definition Accessor.hpp:299
std::enable_if< if_remainder< U >::value, U >::type operator%(U _index) const
Definition Accessor.hpp:328
std::enable_if< if_subtraction< U >::value, U >::type operator-(U _index) const
Definition Accessor.hpp:307
std::enable_if< if_multiplication< U >::value, U >::type operator*(U _index) const
Definition Accessor.hpp:314
std::enable_if< if_remainder< U >::value, void >::type operator%=(U _index)
Definition Accessor.hpp:375
void operator=(T _set)
Definition Accessor.hpp:337
Accessor(T *_variable)
Definition Accessor.hpp:273
T * operator->()
Definition Accessor.hpp:276
ReadOnly< T > readOnly
Definition Accessor.hpp:269
std::enable_if< if_division< U >::value, U >::type operator/(U _index) const
Definition Accessor.hpp:321
std::enable_if< if_division< U >::value, void >::type operator/=(U _index)
Definition Accessor.hpp:368
std::enable_if< std::is_arithmetic< U >::value, void >::type operator+=(T _index)
Definition Accessor.hpp:347
std::enable_if< if_multiplication< U >::value, void >::type operator*=(U _index)
Definition Accessor.hpp:361
WriteOnly< T > writeOnly
Definition Accessor.hpp:270
std::enable_if< if_subtraction< U >::value, void >::type operator-=(U _index)
Definition Accessor.hpp:354
std::enable_if< if_division< U >::value, void >::type operator/=(U _index)
Definition Accessor.hpp:570
std::enable_if< std::is_arithmetic< U >::value, U >::type operator+(U _plus) const
Definition Accessor.hpp:501
ReadOnly< T > readOnly
Definition Accessor.hpp:466
std::enable_if< std::is_arithmetic< U >::value, void >::type operator+=(T _index)
Definition Accessor.hpp:549
std::enable_if< if_remainder< U >::value, U >::type operator%(U _index) const
Definition Accessor.hpp:530
T * operator->()
Definition Accessor.hpp:478
std::enable_if< if_subtraction< U >::value, U >::type operator-(U _index) const
Definition Accessor.hpp:509
std::enable_if< if_multiplication< U >::value, U >::type operator*(U _index) const
Definition Accessor.hpp:516
CustomAccessor(T *_variable, function< T(T)> _setFunc)
コンストラクタ
Definition Accessor.hpp:474
std::enable_if< if_multiplication< U >::value, void >::type operator*=(U _index)
Definition Accessor.hpp:563
CustomWriteOnly< T > writeOnly
Definition Accessor.hpp:467
std::enable_if< if_division< U >::value, U >::type operator/(U _index) const
Definition Accessor.hpp:523
std::enable_if< if_remainder< U >::value, void >::type operator%=(U _index)
Definition Accessor.hpp:577
void operator=(T _set)
Definition Accessor.hpp:539
std::enable_if< if_subtraction< U >::value, void >::type operator-=(U _index)
Definition Accessor.hpp:556
public空間に置くことで,自らが定義したT*のSetterを提供します
Definition Accessor.hpp:389
T * variable
Definition Accessor.hpp:391
std::enable_if< if_subtraction< U >::value, void >::type operator-=(U _index)
Definition Accessor.hpp:428
void operator=(T _set)
Definition Accessor.hpp:404
std::enable_if< if_multiplication< U >::value, void >::type operator*=(U _index)
Definition Accessor.hpp:435
T * operator->()
Definition Accessor.hpp:412
std::enable_if< std::is_arithmetic< U >::value, void >::type operator+=(T _index)
Definition Accessor.hpp:421
std::enable_if< if_division< U >::value, void >::type operator/=(U _index)
Definition Accessor.hpp:442
function< T(T)> SetFunc
Definition Accessor.hpp:392
std::enable_if< if_remainder< U >::value, void >::type operator%=(U _index)
Definition Accessor.hpp:449
CustomWriteOnly(T *_variable, function< T(T)> _setFunc)
コンストラクタ
Definition Accessor.hpp:399
public空間に置くことで,T*のSetterを提供します
Definition Accessor.hpp:117
const T * operator->() const
Definition Accessor.hpp:135
T * variable
Definition Accessor.hpp:119
ReadOnly(T *_variable)
Definition Accessor.hpp:122
std::enable_if< if_subtraction< U >::value, U >::type operator-(U _index) const
Definition Accessor.hpp:157
std::enable_if< if_remainder< U >::value, U >::type operator%(U _index) const
Definition Accessor.hpp:178
std::enable_if< std::is_arithmetic< U >::value, U >::type operator+(U _plus) const
Definition Accessor.hpp:149
std::enable_if< if_division< U >::value, U >::type operator/(U _index) const
Definition Accessor.hpp:171
std::enable_if< if_multiplication< U >::value, U >::type operator*(U _index) const
Definition Accessor.hpp:164
public空間に置くことで,T*のGetterを提供します
Definition Accessor.hpp:195
void operator=(T _set)
Definition Accessor.hpp:207
T * variable
Definition Accessor.hpp:197
std::enable_if< std::is_arithmetic< U >::value, void >::type operator+=(T _index)
Definition Accessor.hpp:224
std::enable_if< if_subtraction< U >::value, void >::type operator-=(U _index)
Definition Accessor.hpp:231
std::enable_if< if_division< U >::value, void >::type operator/=(U _index)
Definition Accessor.hpp:245
std::enable_if< if_multiplication< U >::value, void >::type operator*=(U _index)
Definition Accessor.hpp:238
T * operator->()
Definition Accessor.hpp:214
std::enable_if< if_remainder< U >::value, void >::type operator%=(U _index)
Definition Accessor.hpp:252
WriteOnly(T *_variable)
Definition Accessor.hpp:200
Definition Accessor.hpp:110