Theolizer  Version.1.2.0
serializer for C++ / Do you want to update your classes easily ?
base.h
1 //############################################################################
2 // Theolizer全体のベース部
3 /*
4  © 2016 Theoride Technology (http://theolizer.com/) All Rights Reserved.
5  "Theolizer" is a registered trademark of Theoride Technology.
6 
7  "Theolizer" License
8  In the case where you are in possession of a valid “Theolizer” License,
9  you may use this file in accordance with the terms and conditions of
10  the use license determined by Theoride Technology.
11 
12  General Public License Version 3 ("GPLv3")
13  You may use this file in accordance with the terms and conditions of
14  GPLv3 published by Free Software Foundation.
15  Please confirm the contents of GPLv3 at https://www.gnu.org/licenses/gpl.txt .
16  A copy of GPLv3 is also saved in a LICENSE.TXT file.
17 
18  商用ライセンス
19  あなたが有効なTheolizer商用ライセンスを保持している場合、
20  セオライド テクノロジーの定める使用許諾書の条件に従って、
21  このファイルを取り扱うことができます。
22 
23  General Public License Version 3(以下GPLv3)
24  Free Software Foundationが公表するGPLv3の使用条件に従って、
25  あなたはこのファイルを取り扱うことができます。
26  GPLv3の内容を https://www.gnu.org/licenses/gpl.txt にて確認して下さい。
27  またGPLv3のコピーをLICENSE.TXTファイルにおいてます。
28 */
29 //############################################################################
30 
31 #if !defined(THEOLIZER_INTERNAL_BASE_H)
32 #define THEOLIZER_INTERNAL_BASE_H
33 
34 #if defined(__GNUC__)
35  #include <cxxabi.h> // for Demangle for GCC
36 #endif
37 
38 #include "../rbfor.h" // インクルード漏れ防止のため最初
39 
40 #include <iostream>
41 #include <string>
42 #include <vector>
43 #include <memory> // for unique_ptr
44 #include <chrono>
45 
46 #include <type_traits>
47 #include <typeindex>
48 
49 //############################################################################
50 // Begin
51 //############################################################################
52 
53 namespace theolizer
54 {
55 
56 //############################################################################
57 // メモリリーク検出用(MSVCのみ有効)
58 // boost 1.64.0を使う時、これが原因でエラーになるので止める。
59 //############################################################################
60 
61 #if defined(_MSC_VER) && defined(_DEBUG)
62 // #define new new(_NORMAL_BLOCK, THEOLIZER_INTERNAL_FILE, __LINE__)
63 #endif
64 
65 //############################################################################
66 // 管理用定義
67 //############################################################################
68 
69 // ***************************************************************************
70 // 文字列
71 // ***************************************************************************
72 
73 #define THEOLIZER_INTERNAL_LICENSE "" //"licensed under GPLv3 or lator."
74 
75 #define THEOLIZER_INTERNAL_PRODUCT_NAME "Theolizer"
76 
77 #define THEOLIZER_INTERNAL_COPYRIGHT "Copyright (C) 2016 Yohinori Tahara (Theoride Technology)"
78 
79 #define THEOLIZER_INTERNAL_BUG "Theolizer bug. Please report to http://theoride.com"
80 
81 // ***************************************************************************
82 // 重要機能の許可/禁止
83 // ***************************************************************************
84 
85 // メタ・シリアライザ・コードを出力する
86 //#define THEOLIZER_INTERNAL_ENABLE_META_SERIALIZER
87 
88 //############################################################################
89 // ユーティリティ
90 //############################################################################
91 
92 namespace internal
93 {
94 #ifndef THEOLIZER_INTERNAL_DOXYGEN
95 
96 // ***************************************************************************
97 // MSVCの警告を止める
98 // 意図的な使用に対して警告を止めるために用いる
99 // ***************************************************************************
100 
101 #if defined(__GNUC__)
102  #define THEOLIZER_INTERNAL_UNUSED __attribute__ ((unused))
103 #else
104  #define THEOLIZER_INTERNAL_UNUSED
105 #endif
106 
107 // ***************************************************************************
108 // 文字列化
109 // ***************************************************************************
110 
111 #define THEOLIZER_INTERNAL_STRINGIZE(...) THEOLIZER_INTERNAL_STRINGIZE_I(__VA_ARGS__)
112 #define THEOLIZER_INTERNAL_STRINGIZE_I(...) #__VA_ARGS__ ""
113 
114 // ***************************************************************************
115 // シンボルの結合
116 // ***************************************************************************
117 
118 #define THEOLIZER_INTERNAL_CAT(a, b) THEOLIZER_INTERNAL_CAT_I(a, b)
119 #define THEOLIZER_INTERNAL_CAT_I(a, b) a ## b
120 
121 // ***************************************************************************
122 // 先頭取り出し
123 // ***************************************************************************
124 
125 #define THEOLIZER_INTERNAL_FIRST(dFirst, ...) dFirst
126 
127 // ***************************************************************************
128 // マクロ展開処理
129 // ***************************************************************************
130 
131 #define THEOLIZER_INTERNAL_EXPAND(P) P
132 
133 // ***************************************************************************
134 // マクロFOR
135 // 1個から8個までループ可能
136 // THEOLIZER_INTERNAL_FOR(MACRO, ...)
137 // ...部に1個から8個の要素を書くことで、下記が要素数分展開される
138 // MACRO(要素)
139 // ***************************************************************************
140 
141 #define THEOLIZER_INTERNAL_FOR(S,...) \
142  static_assert( \
143  (!theolizer::internal::isEmpty(THEOLIZER_INTERNAL_STRINGIZE(__VA_ARGS__)))\
144  && (theolizer::internal::countComma(THEOLIZER_INTERNAL_STRINGIZE(__VA_ARGS__))<8),\
145  "Bad number of elements(1..8) in THEOLIZER_INTERNAL_FOR."); \
146  THEOLIZER_INTERNAL_FOR_I(THEOLIZER_INTERNAL_FORR(__VA_ARGS__),S,__VA_ARGS__)
147 
148 // ---<<< 内部処理用 >>>---
149 
150 #define THEOLIZER_INTERNAL_FORX1(S,P,...) S(P)
151 #define THEOLIZER_INTERNAL_FORX2(S,P,...) S(P);\
152  THEOLIZER_INTERNAL_EXPAND(THEOLIZER_INTERNAL_FORX1(S,__VA_ARGS__))
153 #define THEOLIZER_INTERNAL_FORX3(S,P,...) S(P);\
154  THEOLIZER_INTERNAL_EXPAND(THEOLIZER_INTERNAL_FORX2(S,__VA_ARGS__))
155 #define THEOLIZER_INTERNAL_FORX4(S,P,...) S(P);\
156  THEOLIZER_INTERNAL_EXPAND(THEOLIZER_INTERNAL_FORX3(S,__VA_ARGS__))
157 #define THEOLIZER_INTERNAL_FORX5(S,P,...) S(P);\
158  THEOLIZER_INTERNAL_EXPAND(THEOLIZER_INTERNAL_FORX4(S,__VA_ARGS__))
159 #define THEOLIZER_INTERNAL_FORX6(S,P,...) S(P);\
160  THEOLIZER_INTERNAL_EXPAND(THEOLIZER_INTERNAL_FORX5(S,__VA_ARGS__))
161 #define THEOLIZER_INTERNAL_FORX7(S,P,...) S(P);\
162  THEOLIZER_INTERNAL_EXPAND(THEOLIZER_INTERNAL_FORX6(S,__VA_ARGS__))
163 #define THEOLIZER_INTERNAL_FORX8(S,P,...) S(P);\
164  THEOLIZER_INTERNAL_EXPAND(THEOLIZER_INTERNAL_FORX7(S,__VA_ARGS__))
165 
166 #define THEOLIZER_INTERNAL_FORN(_1, _2, _3, _4, _5, _6, _7, _8, N, ...) N
167 #define THEOLIZER_INTERNAL_FORR_I(...)\
168  THEOLIZER_INTERNAL_EXPAND(THEOLIZER_INTERNAL_FORN(__VA_ARGS__))
169 #define THEOLIZER_INTERNAL_FORR(...)\
170  THEOLIZER_INTERNAL_FORR_I(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1, 0)
171 #define THEOLIZER_INTERNAL_FOR_I(N,S,...) \
172  THEOLIZER_INTERNAL_EXPAND \
173  ( \
174  THEOLIZER_INTERNAL_CAT(THEOLIZER_INTERNAL_FORX,N)(S,__VA_ARGS__) \
175  )
176 
177 //----------------------------------------------------------------------------
178 // 文字列処理constexpr関数
179 //----------------------------------------------------------------------------
180 
181 // ---<<< 文字列が空かどうか判定する >>>---
182 
183 constexpr bool isEmpty(char const* p)
184 {
185  return (*p == 0);
186 }
187 
188 // ---<<< 文字列内の','の数を返却する >>>---
189 
190 constexpr unsigned countComma(char const* p)
191 {
192  return (*p == 0)? // if
193  0
194  :(*p == ',')? // else if
195  countComma(p+1)+1
196  : // else
197  countComma(p+1);
198 }
199 
200 // ***************************************************************************
201 // 静的にファイル名抽出
202 // ***************************************************************************
203 
204 constexpr char const* stripPathImpl(char const* iPath, char const* iLast)
205 {
206  return (!*iPath)?
207  iLast
208  : ((*iPath == '/') || (*iPath == '\\'))?
209  stripPathImpl(iPath+1, iPath+1)
210  :
211  stripPathImpl(iPath+1, iLast);
212 }
213 
214 constexpr char const* stripPath(char const* iPath)
215 {
216  return stripPathImpl(iPath, iPath);
217 }
218 
219 #define THEOLIZER_INTERNAL_FILE theolizer::internal::stripPath(__FILE__)
220 
221 // ***************************************************************************
222 // 高精度タイマ・クラス
223 // コンストラクトから、もしくは、前回取得した時からの経過時間を返却する。
224 // iUpdateがfalseの時、経過時間を更新しない。
225 // ***************************************************************************
226 
227 class FineTimer
228 {
229 private:
230  std::chrono::system_clock::time_point mStartTime;
231 
232 public:
233  FineTimer() { mStartTime=std::chrono::system_clock::now(); }
234 
235  int64_t GetmSec(bool iUpdate=true)
236  {
237  std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
238  auto duration = now - mStartTime;
239  if (iUpdate) mStartTime=now;
240  return std::chrono::duration_cast<
241  std::chrono::milliseconds>(duration).count();
242  }
243 
244  int64_t GetuSec(bool iUpdate=true)
245  {
246  std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
247  auto duration = now - mStartTime;
248  if (iUpdate) mStartTime=now;
249  return std::chrono::duration_cast<
250  std::chrono::microseconds>(duration).count();
251  }
252 };
253 
254 // ***************************************************************************
255 // 型情報取得(TYPENAMEマクロ)
256 // ***************************************************************************
257 
258 // libToolingとリンクする時、RTTIを有効にできない。
259 // ドライバのみlibToolingとリンクするのでドライバでは、型情報取得機能を削除する
260 
261 #ifndef THEOLIZER_INTERNAL_DRIVER
262 
263 // ---------------------------------------------------------------------------
264 // GCC用
265 // ---------------------------------------------------------------------------
266 
267 #if defined(__GNUC__)
268 
269 template<typename tType>
270 class GccTypeName
271 {
272 private:
273  static void use(GccTypeName const&) {}
274 
275  char* mName;
276  GccTypeName() : mName(0)
277  {
278  int status = 0;
279  mName = abi::__cxa_demangle(typeid(tType).name(), 0, 0, &status);
280  }
281  ~GccTypeName() {std::free(mName);}
282 
283 public:
284  static GccTypeName& getInstance()
285  {
286  static GccTypeName instance;
287  use(instance);
288  return instance;
289  }
290  char const* get()
291  {
292  return (mName)?mName:"\"demagle error\"";
293  }
294  // コピー/ムーブ禁止
295  GccTypeName(GccTypeName const&) = delete;
296  GccTypeName(GccTypeName&&) = delete;
297  GccTypeName& operator=(GccTypeName const&) = delete;
298  GccTypeName& operator=(GccTypeName&&) = delete;
299 };
300 
301 // 中継
302 template<typename tType>
303 char const* getTypeNameImpl()
304 {
305  return GccTypeName<tType>::getInstance().get();
306 }
307 
308 #if 0 // 不要な筈(未テスト)
309 // type_indexから生成
310 std::string getCppTypeName(std::type_index iStdTypeIndex)
311 {
312  int status = 0;
313  char* aName = abi::__cxa_demangle(iStdTypeIndex.name(), 0, 0, &status);
314  std::string ret(aName);
315  free(aName);
316  return ret;
317 }
318 #endif
319 
320 // ---------------------------------------------------------------------------
321 // その他のコンパイラ用
322 // ---------------------------------------------------------------------------
323 
324 #else
325 
326 template<typename tType>
327 char const* getTypeNameImpl()
328 {
329  return typeid(tType).name();
330 }
331 
332 #if 0 // 不要な筈(未テスト)
333 // type_indexから生成
334 std::string getCppTypeName(std::type_index iStdTypeIndex)
335 {
336  return std::string(iStdTypeIndex.name());
337 }
338 #endif
339 
340 #endif
341 
342 // ---------------------------------------------------------------------------
343 // 中継クラス
344 // ---------------------------------------------------------------------------
345 
346 template<typename tType>
347 struct TypeNameImpl
348 {
349  static char const* get(bool iIsRough=false)
350  {
351  if (iIsRough)
352  {
353  return getTypeNameImpl<tType>();
354  }
355  else
356  {
357  char const* aName=getTypeNameImpl<TypeNameImpl>();
358  char const* p;
359  for (p=aName; (*p != '<') && (*p != 0); ++p)
360  ;
361  return (*p)?p:aName;
362  }
363  }
364 };
365 
366 // ---------------------------------------------------------------------------
367 // マクロ
368 // VAR無しは、型を与える。
369 // VAR付きは、インスタンスを与える。
370 // ROUGH付きは、constと参照がついていてもを区別しない。
371 // ---------------------------------------------------------------------------
372 
373 #define THEOLIZER_INTERNAL_TYPE_NAME(dType) \
374  theolizer::internal::TypeNameImpl<dType>::get()
375 
376 #define THEOLIZER_INTERNAL_TYPE_NAME_VAR(dVar) \
377  theolizer::internal::TypeNameImpl<decltype(dVar)>::get()
378 
379 #define THEOLIZER_INTERNAL_TYPE_NAME_ROUGH(dType) \
380  theolizer::internal::TypeNameImpl<dType>::get(true)
381 
382 #define THEOLIZER_INTERNAL_TYPE_NAME_VAR_ROUGH(dVar) \
383  theolizer::internal::TypeNameImpl<decltype(dVar)>::get(true)
384 
385 // ***************************************************************************
386 // 型情報取得(getNameByTypeInfo)
387 // ***************************************************************************
388 
389 THEOLIZER_INTERNAL_DLL std::string getNameByTypeInfo(std::type_index aTypeIndex);
390 
391 // ***************************************************************************
392 // ドライバ向けダミー定義
393 // ***************************************************************************
394 
395 #else
396 
397 #define THEOLIZER_INTERNAL_TYPE_NAME(dType) ""
398 #define THEOLIZER_INTERNAL_TYPE_NAME_VAR(dVar) ""
399 #define THEOLIZER_INTERNAL_TYPE_NAME_ROUGH(dType) ""
400 #define THEOLIZER_INTERNAL_TYPE_NAME_VAR_ROUGH(dVar) ""
401 inline std::string getNameByTypeInfo(std::type_index aTypeIndex) {return "";}
402 
403 #endif // THEOLIZER_INTERNAL_DRIVER
404 
405 // ***************************************************************************
406 // テンプレート・メタ・プログラミング補助ツール群
407 // ***************************************************************************
408 
409 //----------------------------------------------------------------------------
410 // std::enable_if<>短縮
411 //----------------------------------------------------------------------------
412 
413 template<bool tBool, class tThen = void>
414 using EnableIf=typename std::enable_if<tBool, tThen>::type;
415 
416 //----------------------------------------------------------------------------
417 // 常にvoidとなる型
418 //----------------------------------------------------------------------------
419 
420 template <class>
421 struct Ignore
422 {
423  typedef void type;
424  static const bool kTrue = true;
425  static const bool kFalse = false;
426 };
427 
428 //----------------------------------------------------------------------------
429 // const/volatile外し
430 // ポインタ、参照、配列の型からconst/volatileを外す
431 //----------------------------------------------------------------------------
432 
433 template<typename tType, class tEnable=void>
434 class RemoveCV
435 {
436 public:
437  typedef tType type;
438 };
439 template<typename tType>
440 class RemoveCV<tType, EnableIf<std::is_pointer<tType>::value>>
441 {
442  typedef typename std::remove_pointer<tType>::type Type0;
443  typedef typename std::remove_cv<Type0>::type Type1;
444  typedef typename RemoveCV<Type1>::type Type2;
445 public:
446  typedef typename std::add_pointer<Type2>::type type;
447 };
448 template<typename tType>
449 class RemoveCV<tType,
450  EnableIf<std::is_lvalue_reference<tType>::value>>
451 {
452  typedef typename std::remove_reference<tType>::type Type0;
453  typedef typename std::remove_cv<Type0>::type Type1;
454  typedef typename RemoveCV<Type1>::type Type2;
455 public:
456  typedef typename std::add_lvalue_reference<Type2>::type type;
457 };
458 template<typename tType>
459 class RemoveCV<tType, EnableIf<std::is_array<tType>::value>>
460 {
461  static size_t const kExtent=std::extent<tType>::value;
462 
463  typedef typename std::remove_extent<tType>::type Type0;
464  typedef typename std::remove_cv<Type0>::type Type1;
465  typedef typename RemoveCV<Type1>::type Type2;
466 public:
467  typedef typename RemoveCV::Type2 type[kExtent];
468 };
469 
470 //----------------------------------------------------------------------------
471 // ()解除マクロ
472 //----------------------------------------------------------------------------
473 
474 #define THEOLIZER_INTERNAL_UNPAREN(...) __VA_ARGS__
475 
476 //----------------------------------------------------------------------------
477 // 大小比較演算子
478 // <や>を使うとtemplateの<>の対応付けが難しくなる
479 //----------------------------------------------------------------------------
480 
481 #define THEOLIZER_GE >=
482 #define THEOLIZER_GT >
483 #define THEOLIZER_LE <=
484 #define THEOLIZER_LT <
485 
486 //----------------------------------------------------------------------------
487 // 関数テンプレートのオーバーロード
488 // 使い方例
489 // template<class tClass, THEOLIZER_INTERNAL_OVERLOAD((bool値))>
490 // void FooFunc(tClass& iInstance) { }
491 // bool値がtrueになる時、オーバーロード関数が実体化される。
492 //----------------------------------------------------------------------------
493 
494 #define THEOLIZER_INTERNAL_OVERLOAD(dJudge) \
495  typename std::enable_if<THEOLIZER_INTERNAL_UNPAREN dJudge, std::nullptr_t>::type=nullptr
496 
497 //----------------------------------------------------------------------------
498 // 各種データ型のコピー
499 //----------------------------------------------------------------------------
500 
501 template<typename tClass>
502 void copyData(tClass& oDestination, tClass const& iSource);
503 
504 // ***************************************************************************
505 // 自動回復ツール
506 // ***************************************************************************
507 
508 template<typename tType>
509 class AutoRestore
510 {
511  tType mBackup;
512  tType& mTarget;
513 
514 public:
515  explicit AutoRestore(tType& iTarget, tType iInitialValue) :
516  mBackup(iTarget), // iTargetの値をmBackupへバックアップ
517  mTarget(iTarget) // iTargetのアドレスをmTargetへ設定
518  {
519  mTarget=iInitialValue;
520  }
521  ~AutoRestore()
522  {
523  mTarget=mBackup;
524  }
525  AutoRestore(AutoRestore const&) = delete;
526  AutoRestore& operator=(AutoRestore const&) = delete;
527 };
528 
529 #endif // THEOLIZER_INTERNAL_DOXYGEN
530 } // namespace internal
531 
532 //############################################################################
533 // バージョン管理情報
534 //############################################################################
535 
536 // Theolizerドライバのビルド時は定義されていない
537 #if !defined(THEOLIZER_INTERNAL_DLL)
538  #define THEOLIZER_INTERNAL_DLL
539 #endif
540 
541 #ifndef THEOLIZER_INTERNAL_EXCLUDE_VERSION_H
542 
543 // namespace内で定義するため、ここでインクルード
544 namespace
545 {
546  #include "version.h"
547 }
548 
549 //! バージョン文字列獲得
550 THEOLIZER_INTERNAL_DLL std::string getVersionString();
551 
552 //! バージョン番号獲得(バージョン文字列獲得の一部)
553 THEOLIZER_INTERNAL_DLL std::string getVersionNo();
554 
555 //! ソース・コードのMD5ハッシュ値獲得(バージョン文字列獲得の一部)
556 THEOLIZER_INTERNAL_DLL std::string getSourcesHash();
557 
558 //! ライブラリ・ヘッダのMD5ハッシュ値獲得(バージョン文字列獲得の一部)
559 THEOLIZER_INTERNAL_DLL std::string getLibraryHash();
560 
561 /*!
562 @brief ライブラリ・バイナリとライブラリ・ヘッダのバージョンが一致している時、true返却
563 @details 不一致の場合、正常に動作しない恐れがあるため、共有ライブラリを使用する時は、
564  checkLibraryHash()がtrueであることをチェックすることを推奨する。
565 */
566 THEOLIZER_INTERNAL_DLL bool checkLibraryHash(char const* iLibraryHash=kTheolizerLibraryHash);
567 
568 #endif //THEOLIZER_INTERNAL_EXCLUDE_VERSION_H
569 
570 //############################################################################
571 // End
572 //############################################################################
573 
574 } // namespace theolizer
575 
576 #endif // THEOLIZER_INTERNAL_BASE_H
theolizer名前空間
Definition: base.h:53
THEOLIZER_INTERNAL_DLL std::string getSourcesHash()
ソース・コードのMD5ハッシュ値獲得(バージョン文字列獲得の一部)
THEOLIZER_INTERNAL_DLL bool checkLibraryHash(char const *iLibraryHash=kTheolizerLibraryHash)
ライブラリ・バイナリとライブラリ・ヘッダのバージョンが一致している時、true返却
THEOLIZER_INTERNAL_DLL std::string getVersionString()
バージョン文字列獲得
char const kTheolizerLibraryHash[]
Theolizerライブラリ・ヘッダ・ファイルのハッシュ値
Definition: version.h:44
THEOLIZER_INTERNAL_DLL std::string getVersionNo()
バージョン番号獲得(バージョン文字列獲得の一部)
バージョン番号を自動生成
THEOLIZER_INTERNAL_DLL std::string getLibraryHash()
ライブラリ・ヘッダのMD5ハッシュ値獲得(バージョン文字列獲得の一部)