Theolizer  Version.1.2.0
serializer for C++ / Do you want to update your classes easily ?
core_assorted.h
[詳解]
1 //############################################################################
2 /*!
3 @brief Theolizerライブラリのコア部(型情報リスト)
4 @ingroup TheolizerLib
5 @file core_assorted.h
6 @author Yoshinori Tahara(Theoride Technology)
7 @date 2016/07/18 Created
8 */
9 /*
10  © 2016 Theoride Technology (http://theolizer.com/) All Rights Reserved.
11  "Theolizer" is a registered trademark of Theoride Technology.
12 
13  "Theolizer" License
14  In the case where you are in possession of a valid “Theolizer” License,
15  you may use this file in accordance with the terms and conditions of
16  the use license determined by Theoride Technology.
17 
18  General Public License Version 3 ("GPLv3")
19  You may use this file in accordance with the terms and conditions of
20  GPLv3 published by Free Software Foundation.
21  Please confirm the contents of GPLv3 at https://www.gnu.org/licenses/gpl.txt .
22  A copy of GPLv3 is also saved in a LICENSE.TXT file.
23 
24  商用ライセンス
25  あなたが有効なTheolizer商用ライセンスを保持している場合、
26  セオライド テクノロジーの定める使用許諾書の条件に従って、
27  このファイルを取り扱うことができます。
28 
29  General Public License Version 3(以下GPLv3)
30  Free Software Foundationが公表するGPLv3の使用条件に従って、
31  あなたはこのファイルを取り扱うことができます。
32  GPLv3の内容を https://www.gnu.org/licenses/gpl.txt にて確認して下さい。
33  またGPLv3のコピーをLICENSE.TXTファイルにおいてます。
34 */
35 //############################################################################
36 
37 #if !defined(THEOLIZER_INTERNAL_CORE_ASSORTED_H)
38 #define THEOLIZER_INTERNAL_CORE_ASSORTED_H
39 
40 #include <limits>
41 
42 // ***************************************************************************
43 // 基本ツールのインクルード
44 // ***************************************************************************
45 
46 #include "../report.h"
47 
48 //############################################################################
49 // Begin
50 //############################################################################
51 
52 // ***************************************************************************
53 // DLL用の警告禁止
54 // ***************************************************************************
55 
56 #ifdef _MSC_VER
57  #pragma warning(push)
58  #pragma warning(disable:4100 4251)
59 #endif
60 
61 //############################################################################
62 // グローバル名前空間
63 //############################################################################
64 
65 // ***************************************************************************
66 // 機能をディセーブルするためのシンボル定義
67 // 当面機能をディセーブルするが、復活する可能性を考慮して残すもの
68 // ***************************************************************************
69 
70 #ifndef THEOLIZER_INTERNAL_DOXYGEN
71 
72 //----------------------------------------------------------------------------
73 // TheolizerNonKeepStepとenum型のデバック用
74 //----------------------------------------------------------------------------
75 
76 #if 0
77  #define THEOLIZER_INTERNAL_VER_DEBUG(dStatements) THEOLIZER_INTERNAL_UNPAREN dStatements
78 #else
79  #define THEOLIZER_INTERNAL_VER_DEBUG(dStatements)
80 #endif
81 
82 //----------------------------------------------------------------------------
83 // null参照検出
84 // null参照は未定義動作なので、プログラマの責任で回避するべきもの
85 // gcc 6で警告が出るため、null参照検出コードは無効化する
86 //----------------------------------------------------------------------------
87 
88 #define THEOLIZER_INTERNAL_DISABLE_NULL_REFERENCE
89 
90 // ***************************************************************************
91 // THEOLIZER_WRITE_CODE付随処理
92 // 解析しない指示(THEOLIZER_NO_ANALYZE)がなく、
93 // THEOLIZER_WRITE_CODEが未定義なら定義する。
94 // ***************************************************************************
95 
96 #if !defined(THEOLIZER_NO_ANALYZE) && !defined(THEOLIZER_WRITE_CODE)
97  #define THEOLIZER_WRITE_CODE
98 #endif
99 
100 #endif // THEOLIZER_INTERNAL_DOXYGEN
101 
102 // ***************************************************************************
103 /*!
104  @brief ソース自動生成制御
105  @details ドライバにて下記制御を行う<br>
106    環境変数THEOLIZER_DEVELOPER_NAMEが定義されている時、<br>
107    THEOLIZER_PROVIDED_BY()のdVendor(C文字列)と一致したら、<br>
108    THEOLIZER_PROVIDED_BYが展開されたファイル内の自動生成マクロは更新可能<br>
109    そうでない場合に更新を検出したらエラー<br>
110 */
111 // ***************************************************************************
112 
113 #define THEOLIZER_PROVIDED_BY(dVendor)
114 
115 //############################################################################
116 // theolizer名前空間定義
117 //############################################################################
118 
119 //! theolizer名前空間
120 namespace theolizer{namespace destination{ }}
122 
123 namespace theolizer
124 {
125 
126 //############################################################################
127 // ユーティリティ
128 //############################################################################
129 
130 namespace internal
131 {
132 #ifndef THEOLIZER_INTERNAL_DOXYGEN
133 
134 // ***************************************************************************
135 // 異なるコンテナをポリモーフィックに枚挙するためのRange
136 // RBForRangeテクニックを応用しているが、
137 // RBForRangeを直接は使えないので別途定義した。
138 // ***************************************************************************
139 
140 //----------------------------------------------------------------------------
141 // 範囲ベースforへ渡すリファレンサー(RBForReferencerの特化)
142 //----------------------------------------------------------------------------
143 
144 template<class tPolyRangeBase, class tValueType>
145 class PolyReferencer
146 {
147  tPolyRangeBase& mPolyRange;
148 public:
149  PolyReferencer(tPolyRangeBase& iPolyRange) : mPolyRange(iPolyRange)
150  { }
151 
152  tValueType& operator*()
153  {
154  THEOLIZER_INTERNAL_ASSERT(mPolyRange.mHolder.get(), THEOLIZER_INTERNAL_BUG);
155  return mPolyRange.mHolder->front();
156  }
157  tValueType const& operator*() const
158  {
159  THEOLIZER_INTERNAL_ASSERT(mPolyRange.mHolder.get(), THEOLIZER_INTERNAL_BUG);
160  return mPolyRange.mHolder->front();
161  }
162  void operator++()
163  {
164  THEOLIZER_INTERNAL_ASSERT(mPolyRange.mHolder.get(), THEOLIZER_INTERNAL_BUG);
165  mPolyRange.mHolder->drop_front();
166  }
167  bool operator!=(PolyReferencer const& iRhs) const
168  {
169  if (!mPolyRange.mHolder.get())
170  return false;
171  return !mPolyRange.mHolder->empty();
172  }
173 };
174 
175 //----------------------------------------------------------------------------
176 // 枚挙用Range
177 //----------------------------------------------------------------------------
178 
179 template<class tValueType>
180 class PolyRange
181 {
182 
183 // ---<<< 基底クラス >>>---
184 
185  struct HolderBase
186  {
187  virtual tValueType & front() = 0;
188  virtual tValueType const& front() const = 0;
189  virtual void drop_front() = 0;
190  virtual bool empty() const = 0;
191  virtual std::size_t size() = 0;
192 
193  // これがないとmsvc 2015の「反復子のデバッグのサポート」用の
194  // イテレータのデストラクタが呼ばれないため、異常動作する。
195  virtual ~HolderBase() { }
196  };
197 
198 // ---<<< 実クラス >>>---
199 
200  template<typename tIterator>
201  struct Holder : public HolderBase
202  {
203  tIterator mBegin;
204  tIterator mEnd;
205  std::size_t mCount;
206 
207  Holder(tIterator&& iBegin, tIterator&& iEnd, std::size_t iCount) :
208  mBegin(std::forward<tIterator>(iBegin)),
209  mEnd (std::forward<tIterator>(iEnd)),
210  mCount(iCount)
211  { }
212  ~Holder() = default;
213 
214  tValueType& front()
215  {
216  return *mBegin;
217  }
218  tValueType const& front() const
219  {
220  return *mBegin;
221  }
222  void drop_front()
223  {
224  ++mBegin;
225  --mCount;
226  }
227  bool empty() const
228  {
229  return mBegin == mEnd;
230  }
231  std::size_t size()
232  {
233  return mCount;
234  }
235  };
236 
237 // ---<<< 各種設定 >>>---
238 
239  template<class, class> friend class PolyReferencer;
240  typedef PolyReferencer<PolyRange, tValueType> PolyReferencer_t;
241 
242 // ---<<< 記録領域 >>>---
243 
244  std::unique_ptr<HolderBase> mHolder;
245 
246 // ---<<< コンストラクタ >>>---
247 
248 public:
249  PolyRange() { }
250 
251  template<typename tIterator>
252  PolyRange(tIterator&& iBegin, tIterator&& iEnd, std::size_t iCount) :
253  mHolder
254  (
255  new Holder<tIterator>
256  (
257  std::forward<tIterator>(iBegin),
258  std::forward<tIterator>(iEnd),
259  iCount
260  )
261  )
262  { }
263 
264  PolyReferencer_t begin() {return PolyReferencer_t(*this);}
265  PolyReferencer_t end() {return PolyReferencer_t(*this);}
266  std::size_t size()
267  {
268  if (!mHolder.get())
269  return 0;
270  return mHolder->size();
271  }
272 };
273 
274 // ***************************************************************************
275 // 生配列の型定義
276 // Array<型, 要素数...>にて生配列の型になる
277 // 下記2つは同じ定義である。
278 // theolizer::Array<int, 10, 20> aIntArray;
279 // int aIntArray[10][20];
280 // このテンプレートで配列の参照を下記のように定義することができる。
281 // theolizer::Array<int, 10>& aInt10;
282 // int (&aInt)[10];
283 // CoveredArray<型, 要素数...>は上記と同じ記憶領域配置だが型が異なる
284 // CoveredArray<int, 2, 3>は下記
285 // class ArrayImpl // == CoveredArray
286 // {
287 // class ArrayImpl
288 // {
289 // class ArrayImpl
290 // {
291 // int mElement;
292 // } mElements[3];
293 // } mElements[2];
294 // };
295 // ***************************************************************************
296 
297 template<class tType, size_t... tDims>
298 struct ArrayImpl
299 {
300  typedef tType type;
301  typedef tType CoveredElements;
302 
303  // オフセットを合わせるため、中身を定義
304  CoveredElements mElement;
305 
306  // 中身へのアクセス
307  CoveredElements& getElement() {return mElement;}
308 };
309 
310 template<class tType, size_t tFirst, size_t... tDims>
311 struct ArrayImpl<tType, tFirst, tDims...>
312 {
313  typedef typename ArrayImpl<tType, tDims...>::type type[tFirst];
314  typedef ArrayImpl<tType, tDims...> CoveredElements[tFirst];
315 
316  // オフセットを合わせるため、中身を定義
317  CoveredElements mElements;
318 
319  // 1次元配列としてアクセス
320  CoveredElements& getElements() {return mElements;}
321 };
322 
323 template<class tType, size_t... tDims>
324 using Array = typename ArrayImpl<tType, tDims...>::type;
325 
326 template<class tType, size_t... tDims>
327 using CoveredArray = ArrayImpl<tType, tDims...>;
328 
329 //############################################################################
330 // エラー報告サービス群
331 //############################################################################
332 
333 // ***************************************************************************
334 // エラー・チェック用サーピス群
335 // ***************************************************************************
336 
337 THEOLIZER_INTERNAL_DLL void checkDataShort(bool iIsPass, std::string const& iLoc);
338 THEOLIZER_INTERNAL_DLL void checkExtraData(bool iIsPass, std::string const& iLoc);
339 
340 //############################################################################
341 // 保存先指定
342 //############################################################################
343 
344 // ***************************************************************************
345 // 内部処理用アイテム群
346 // ***************************************************************************
347 
348 //----------------------------------------------------------------------------
349 // ビット列処理クラス
350 //----------------------------------------------------------------------------
351 
352 class THEOLIZER_INTERNAL_DLL BitString
353 {
354  static int const kUnsignedSize=std::numeric_limits<unsigned>::digits;
355  static unsigned const kUnsignedMax =std::numeric_limits<unsigned>::max();
356  std::unique_ptr<unsigned[]> mBitList; // 記録領域
357  unsigned mDataCount; // 保持しているunsignedの数
358 
359  // 必要なら記録領域追加
360  void expandList(unsigned iIndex);
361 public:
362  BitString() : mBitList(), mDataCount(0) { }
363 
364  BitString(BitString&& iRhs) noexcept :
365  mBitList(std::move(iRhs.mBitList)),
366  mDataCount(iRhs.mDataCount)
367  { }
368 
369  // 指定bit追加
370  void add(unsigned iBitNo);
371 
372  // 指定unsigned追加
373  void add(unsigned iIndex, unsigned iData);
374 
375  // 指定bit判定
376  bool isOne(unsigned iBitNo) const;
377 
378  // 文字列化
379  std::string to_string(unsigned iStart=0, unsigned iEnd=kUnsignedMax) const;
380 
381  // unsigned単位のイテレータ(bit単位は必要ないので省略)
382  unsigned* begin() const {return &mBitList[0];}
383  unsigned* end() const {return &mBitList[mDataCount];}
384 };
385 
386 #endif // THEOLIZER_INTERNAL_DOXYGEN
387 } // namespace internal
388 
389 // ***************************************************************************
390 // 保存先シンボル定義用ツール群
391 // ***************************************************************************
392 
393 //----------------------------------------------------------------------------
394 /*!
395 @brief 保存先シンボルを定義するscoped enum型
396 @details 通常の整数型で間違って保存先指定されなよう、scoped enumを用いる。<br>
397  実際にはunsigned型で定義された値を、Destinationへstatic_castしている。
398 */
399 //----------------------------------------------------------------------------
400 
401 enum class Destination : unsigned { };
402 
403 //----------------------------------------------------------------------------
404 // ビット番号管理ツール
405 //----------------------------------------------------------------------------
406 
407 #ifndef THEOLIZER_INTERNAL_DOXYGEN
408 namespace internal
409 {
410 namespace
411 {
412 
413 // ---<<< ビット番号自動生成 >>>---
414 
415 namespace bits
416 {
417 enum : unsigned {All=0};
418 } // namespace bits
419 
420 } // namespace
421 } // namespace internal
422 
423 //----------------------------------------------------------------------------
424 // ユーザが使用する保存先シンボルを定義
425 // 名前空間:theolizerD
426 //
427 // theolizerD::All 全て保存する
428 //----------------------------------------------------------------------------
429 
430 namespace destination
431 {
432 namespace
433 {
434  Destination const All=static_cast<Destination>(internal::bits::All);
435 } // namespace
436 } // namespace destination
437 
438 //----------------------------------------------------------------------------
439 // 保存先シンボル定義マクロ
440 //----------------------------------------------------------------------------
441 
442 #define THEOLIZER_INTERNAL_DESTINATION(dSymbol) \
443  namespace destination{namespace{ \
444  Destination const dSymbol=static_cast<Destination>(internal::bits::dSymbol);\
445  }} /* namespace destination */ \
446 
447 // ***************************************************************************
448 // 保存先を保持するクラス
449 // 名前空間:theolizer
450 // ***************************************************************************
451 
452 namespace internal
453 {
454 
455 class THEOLIZER_INTERNAL_DLL Destinations
456 {
457  static unsigned const kAlways = (1u << static_cast<unsigned>(theolizerD::All));
458  internal::BitString mDestinations;
459 public:
460 
461 //----------------------------------------------------------------------------
462 // コンストラクタ
463 //----------------------------------------------------------------------------
464 
465  Destinations()
466  { }
467 
468  Destinations(std::initializer_list<Destination> const& iDestinationList)
469  {
470  add(iDestinationList);
471  }
472 
473  Destinations(Destinations&& iRhs) noexcept :
474  mDestinations(std::move(iRhs.mDestinations))
475  { }
476 
477 //----------------------------------------------------------------------------
478 // 要素追加
479 //----------------------------------------------------------------------------
480 
481  void add(std::initializer_list<Destination> const& iDestinationList)
482  {
483  for (auto destination : iDestinationList)
484  {
485  unsigned aBitNo = static_cast<unsigned>(destination);
486  mDestinations.add(aBitNo);
487  }
488  }
489 
490  void add(Destinations const& iRhs)
491  {
492  for (auto&& aIndexer : getRBForIndexer(iRhs.mDestinations))
493  {
494  mDestinations.add(static_cast<unsigned>(aIndexer.getIndex()), aIndexer.front());
495  }
496  }
497 
498 //----------------------------------------------------------------------------
499 // 一致判定
500 //----------------------------------------------------------------------------
501 
502  bool isMatch(Destinations const& iRhs, bool iIsJustMatch=false) const
503  {
504  auto aLhs=mDestinations.begin();
505  bool aFirst=true;
506  for (auto aRhs : iRhs.mDestinations)
507  {
508  if (aFirst)
509  {
510  aFirst=false;
511  // JustMatch出ない時は、どちらか一方のAlwayが1ならtrue
512  if ((!iIsJustMatch) && ((*aLhs & 1) || (aRhs & 1)))
513  {
514  return true;
515  }
516  }
517 
518  if (*aLhs & aRhs) {
519  return true;
520  }
521  }
522  return false;
523  }
524 
525 //----------------------------------------------------------------------------
526 // 表示用
527 //----------------------------------------------------------------------------
528 
529  std::string to_string() const
530  {
531  return mDestinations.to_string(0, 1)+":"+mDestinations.to_string(1);
532  }
533  friend std::ostream& operator<<(std::ostream& iOStream, Destinations const& iDestinations)
534  {
535  iOStream << iDestinations.to_string();
536  return iOStream;
537  }
538 };
539 
540 // ***************************************************************************
541 // グローバル・バージョン番号管理
542 // クラス・バージョンをまとめてグローバル・バージョンとして管理する
543 // そのため、クラスのリストとそれぞれのクラス・バージョンが対応する
544 // グローバル・バージョン番号を対応付ける。
545 // ***************************************************************************
546 
547 //----------------------------------------------------------------------------
548 // キーとローカル・バージョン番号リスト・インデックス
549 //----------------------------------------------------------------------------
550 
551 struct GlobalVersionKey
552 {
553  std::type_index mTypeIndex;
554  std::size_t mListIndex;
555  GlobalVersionKey(std::type_index iTypeIndex, std::size_t iListIndex) :
556  mTypeIndex(iTypeIndex), mListIndex(iListIndex)
557  { }
558 };
559 
560 //----------------------------------------------------------------------------
561 // 実装用関数宣言
562 //----------------------------------------------------------------------------
563 
564 // キー登録
565 THEOLIZER_INTERNAL_DLL void addGlobalVersionKey
566 (
567  GlobalVersionKey const& iKey,
568  std::vector<GlobalVersionKey>& oKeyList
569 );
570 
571 // キー検索
572 THEOLIZER_INTERNAL_DLL bool findGlobalVersionKey
573 (
574  std::vector<GlobalVersionKey> const& iKeyList,
575  std::type_index iTypeIndex,
576  std::size_t& oListIndex
577 );
578 
579 //----------------------------------------------------------------------------
580 // テーブルの基底クラス
581 //----------------------------------------------------------------------------
582 
583 class GlobalVersionNoTableBase
584 {
585 protected:
586  GlobalVersionNoTableBase() { }
587  ~GlobalVersionNoTableBase() { }
588 public:
589  virtual char const* getTableName() const {return "";}
590 
591  virtual unsigned getLocalVersionNo
592  (
593  unsigned iGlobalVersionNo,
594  std::type_index iStdTypeIndex
595  ) const = 0;
596 
597  virtual unsigned getGlobalVersionNo
598  (
599  unsigned iLocalVersionNo,
600  std::type_index iStdTypeIndex
601  ) const = 0;
602 
603  // コピー/ムーブ禁止(デストラクタ定義がないとis_trivially_copyableになる)
604  GlobalVersionNoTableBase(const GlobalVersionNoTableBase&) = delete;
605  GlobalVersionNoTableBase( GlobalVersionNoTableBase&&) = delete;
606  GlobalVersionNoTableBase& operator=(const GlobalVersionNoTableBase&) = delete;
607  GlobalVersionNoTableBase& operator=( GlobalVersionNoTableBase&&) = delete;
608 };
609 
610 //----------------------------------------------------------------------------
611 // テーブル本体
612 // シングルトン
613 //----------------------------------------------------------------------------
614 
615 template<unsigned uLastGlobalVersionNo>
616 class GlobalVersionNoTable : public GlobalVersionNoTableBase
617 {
618  static_assert(uLastGlobalVersionNo != 0, "Global VersionNo.0 is illegal.");
619 
620 // ---<<< ローカル・バージョン番号のリスト >>>---
621 
622  // 1つで1クラス/enum型のローカル・バージョン番号を保持する
623  struct LocalVersionNo
624  {
625  unsigned mLocalVersionNo[uLastGlobalVersionNo];
626  };
627  // 登録順でローカル・バージョン番号を保持する
628  std::vector<LocalVersionNo> mLocalVersionNoList;
629 
630 // ---<<< std::type_index(キー)とmLocalVersionNoListとの対応表 >>>---
631 
632  // type_indexによるキーでソート
633  std::vector<GlobalVersionKey> mKeyList;
634 
635 // ---<<< シングルトン >>>---
636 
637 protected:
638  GlobalVersionNoTable() { }
639 public:
640  static GlobalVersionNoTableBase* getInstance()
641  {
642  static GlobalVersionNoTable instance;
643  return &instance;
644  }
645 
646 // ---<<< 機能群 >>>---
647 
648  // クラス登録
649  template<typename... tLocalVersionNoList>
650  void add(std::type_info const& iTypeInfo, tLocalVersionNoList... iLocalVersionNoList)
651  {
652  static_assert(sizeof...(tLocalVersionNoList) == uLastGlobalVersionNo,
653  "GlobalVersionNoTable::add() illegal number of parameters.");
654 
655  std::size_t aTypeIndex=mLocalVersionNoList.size();
656  mLocalVersionNoList.push_back(LocalVersionNo{iLocalVersionNoList...});
657  addGlobalVersionKey(GlobalVersionKey(iTypeInfo, aTypeIndex), mKeyList);
658  }
659 
660  // 指定クラスの指定グローバル・バージョン番号に該当するローカル・バージョン番号返却
661  // 未登録クラスは1を返却する(完全自動型なので)
662  unsigned getLocalVersionNo(unsigned iGlobalVersionNo, std::type_index iStdTypeIndex) const
663  {
664  if (iGlobalVersionNo == 0 )
665  {
666  THEOLIZER_INTERNAL_VERSION_ERROR("GlobalVersionNo(%1%) is illegal.", iGlobalVersionNo);
667  }
668  if (uLastGlobalVersionNo < iGlobalVersionNo)
669  {
670  THEOLIZER_INTERNAL_VERSION_ERROR("GlobalVersionNo(%1%) is too big.", iGlobalVersionNo);
671  }
672 
673  std::size_t aListIndex;
674  if (!findGlobalVersionKey(mKeyList, iStdTypeIndex, aListIndex))
675  return 1;
676 
677  unsigned ret = mLocalVersionNoList[aListIndex].mLocalVersionNo[iGlobalVersionNo-1];
678 
679  // 無効な値ならエラー(iGlobalVersionNo時にシリアライズされていなかった時該当する)
680  if (!ret)
681  {
682  THEOLIZER_INTERNAL_DATA_ERROR(
683  u8"Can not process <%1%> for Global VersionNo.%2%",
684  getNameByTypeInfo(iStdTypeIndex),
685  iGlobalVersionNo
686  );
687  }
688  return ret;
689  }
690 
691  // 指定クラスの指定ローカル・バージョン番号に該当する最大のグローバル・バージョン番号返却
692  // 未登録クラスはuLastGlobalVersionNoを返却する
693  unsigned getGlobalVersionNo(unsigned iLocalVersionNo, std::type_index iStdTypeIndex) const
694  {
695  THEOLIZER_INTERNAL_ASSERT(iLocalVersionNo != 0,
696  "GlobalVersionNoTable::getGlobalVersionNo() : iLocalVersionNo is illegal(0).");
697 
698  std::size_t aListIndex;
699  if (!findGlobalVersionKey(mKeyList, iStdTypeIndex, aListIndex))
700  return uLastGlobalVersionNo;
701 
702  unsigned ret;
703  for (ret=uLastGlobalVersionNo; 0 < ret; --ret)
704  {
705  if (mLocalVersionNoList[aListIndex].mLocalVersionNo[ret-1] == iLocalVersionNo)
706  {
707  return ret;
708  }
709  }
710 
711  return uLastGlobalVersionNo;
712  }
713 };
714 
715 //----------------------------------------------------------------------------
716 // ユーザ定義のグローバル・バージョン番号テーブルへのポインタを取込む
717 // 名前空間は、theolizer::internal::匿名::
718 //----------------------------------------------------------------------------
719 
720 namespace
721 {
722  extern GlobalVersionNoTableBase const*const sGlobalVersionNoTable;
723 } // namespace
724 
725 //----------------------------------------------------------------------------
726 // 最新版のグローバル・バージョン番号
727 // 名前空間は、theolizer::匿名::
728 //----------------------------------------------------------------------------
729 
730 } // namespace internal
731 
732 namespace
733 {
734  extern unsigned const kLastGlobalVersionNo;
735 } // namespace
736 
737 namespace internal
738 {
739 
740 //----------------------------------------------------------------------------
741 // ソース自動生成用マクロ
742 //----------------------------------------------------------------------------
743 
744 #define THEOLIZER_GENERATED_GLOBAL_TABLE() \
745  namespace theolizer{namespace internal{namespace{ \
746  GlobalVersionNoTableBase const*const sGlobalVersionNoTable= \
747  GlobalVersionNoTable<1>::getInstance(); \
748  }} /* namespace internal */ \
749  namespace{ \
750  unsigned const kLastGlobalVersionNo=1; \
751  }} /* namespace theolizer */
752 
753 //############################################################################
754 // 型管理用ユーティリティ
755 //############################################################################
756 
757 // ***************************************************************************
758 // 型管理用プライマリ・テンプレート定義
759 // ***************************************************************************
760 
761 } // namespace internal
762 #endif // THEOLIZER_INTERNAL_DOXYGEN
763 
764 } // namespace theolizer
765 
766 // ---<<<< enum型/非侵入型/プリミティブ/ポインタ/参照プライマリー・テンプレート >>>---
767 
768 #ifndef THEOLIZER_INTERNAL_DOXYGEN
769 
770 template<class tClassType>
771 struct TheolizerNonIntrusive {};
772 
773 // ---<<<< 手動型基底クラス用プライマリー・テンプレート >>>---
774 
775 template<class tClassType>
776 class TheolizerBase {};
777 
778 // ---<<<< Non-keep-step型用プライマリー・テンプレート >>>---
779 // プリミティブ/ポインタ/手動型クラス
780 
781 template<class tClassType, class tEnable>
782 struct TheolizerNonKeepStep;
783 
784 // ---<<<< トップ・レベル登録時のバージョン伝達エラー回避用 >>>---
785 // コーディング規約上、tで始まる名前はテンプレート引数だが、
786 // 下記理由により例外とする。
787 // 手動型のTheolizerUserDefine内でシリアライズ/デシリアライズ
788 // 指示する際、THEOLIZER_PROCESS()等のマクロを用いる。
789 // この手動型のシリアライズ/デシリアライズ指定された型を
790 // 当該手動型クラスのメンバ型として登録するために、テンプレート・
791 // パラメータtTheolizerVersionをTHEOLIZER_PROCESS()等のマクロで用いる。
792 // それ以外の場所で、THEOLIZER_PROCESS()等のマクロが使われた時に、
793 // tTheolizerVersionが未定義エラーにならないようここで定義する。
794 
795 struct tTheolizerVersion
796 {
797  template<class tTypeFunc>
798  static void addElement(tTypeFunc iTypeFunc)
799  {
800  }
801 };
802 #endif // THEOLIZER_INTERNAL_DOXYGEN
803 
804 namespace theolizer
805 {
806 
807 // ***************************************************************************
808 /*!
809  @brief 型チェック・モード
810  @details TypeIndexは「型」に割り当てられるインデックス番号。<br>
811  ソフトウェアが起動される時に確定する。<br>
812  InMemoryは、FastSerializer専用。以下の特徴を持つ。<br>
813  変更されていないクラス同士でのみ保存/回復可能な負荷が最も軽いモード。<br>
814  回復時の型チェックを一切行わない。<br>
815  ポインタの先がシリアライズされてなかったら、元のアドレスを回復する。<br>
816  (つまり、そのようなポインタはシャロー・コピーとなる。)
817 */
818 // ***************************************************************************
819 
820 enum class CheckMode
821 {
822  InMemory, // メモリ内動作のみ、かつ、型チェック無し(非公開)
823  TypeCheckInData, // データ内に型名を記録する
824  NoTypeCheck, //!< 型チェック無し
825  TypeCheck, //!< 型名による型チェック
826  TypeCheckByIndex, //!< TypeIndexによる型チェック
827  MetaMode // メタ処理-型定義情報を保存/回復(非公開)
828 };
829 
830 //! CheckModeの表示用オーバーロード
831 THEOLIZER_INTERNAL_DLL std::ostream& operator<<(std::ostream& iOStream, CheckMode iCheckMode);
832 
833 // ***************************************************************************
834 /*!
835 @brief シリアライザが提供する機能(プロパティ)のリスト
836 @details bool hasProperty()に指定するパラメータ<br>
837 */
838 // ***************************************************************************
839 
840 enum class Property
841 {
842  IsSaver, // 保存処理を行う
843  EncodedString, // setCharIsMultiByte()をサポートし、文字列の互換がある
844  SupportModifying, // 変更をサポート(FastSerializerは非対応)
845  BinaryOpen // fstreamをstd::ios_base::binaryモードでオープンする必要がある
846 };
847 
848 //! Propertyの表示用オーバーロード
849 THEOLIZER_INTERNAL_DLL std::ostream& operator<<(std::ostream& iOStream, Property iProperty);
850 
851 namespace internal
852 {
853 #ifndef THEOLIZER_INTERNAL_DOXYGEN
854 
855 // ***************************************************************************
856 // 不正値
857 // ***************************************************************************
858 
859 THEOLIZER_INTERNAL_DLL extern const std::size_t kInvalidSize;
860 
861 // ***************************************************************************
862 // 型分岐用補助ツール
863 // ***************************************************************************
864 
865 //----------------------------------------------------------------------------
866 // 文字列型判定(std::string, std::wstring, std::u16string, std::u32string)
867 //----------------------------------------------------------------------------
868 
869 template<class tClass, class tEnable=void>
870 struct IsStringImpl : public std::false_type
871 { };
872 
873 template<class tClass>
874 struct IsStringImpl
875 <
876  tClass,
877  EnableIf
878  <
879  std::is_same<tClass, std::string>::value
880  || std::is_same<tClass, std::wstring>::value
881  || std::is_same<tClass, std::u16string>::value
882  || std::is_same<tClass, std::u32string>::value
883  >
884 > : public std::true_type
885 { };
886 
887 template<class tClass>
888 struct IsString
889 {
890  static const bool value=IsStringImpl<tClass>::value;
891 };
892 
893 //----------------------------------------------------------------------------
894 // プリミティブ型判定(数値型と文字列型)
895 //----------------------------------------------------------------------------
896 
897 template<typename tType, class tEnable=void>
898 struct IsPrimitiveImpl : public std::false_type
899 { };
900 
901 template<typename tType>
902 struct IsPrimitiveImpl
903 <
904  tType,
905  EnableIf
906  <
907  std::is_arithmetic<tType>::value
908  || IsString<tType>::value
909  >
910 > : public std::true_type
911 { };
912 
913 template<typename tType>
914 struct IsPrimitive
915 {
916  static const bool value=IsPrimitiveImpl<tType>::value;
917 };
918 
919 //----------------------------------------------------------------------------
920 // 侵入型と非侵入型のTheolizerVersion判定
921 //----------------------------------------------------------------------------
922 
923 template<class tClass, class tEnable=void>
924 struct IsTheolizerVersionImpl : public std::false_type
925 { };
926 
927 template<class tClass>
928 struct IsTheolizerVersionImpl
929 <
930  tClass,
931  EnableIf
932  <
933  tClass::Theolizer::kIsVersion
934  >
935 > : public std::true_type
936 { };
937 
938 template<class tClass>
939 struct IsTheolizerVersion
940 {
941  static const bool value=IsTheolizerVersionImpl<tClass>::value;
942 };
943 
944 //----------------------------------------------------------------------------
945 // 手動型用基底クラス(TheolizerBase)判定
946 //----------------------------------------------------------------------------
947 
948 template<class tClass, class tEnable=void>
949 struct IsTheolizerBase : public std::false_type
950 { };
951 
952 template<class tClass>
953 struct IsTheolizerBase
954 <
955  tClass,
956  EnableIf<tClass::kIsTheolizerBase && !IsTheolizerVersion<tClass>::value>
957 > : public std::true_type
958 { };
959 
960 //----------------------------------------------------------------------------
961 // TheolizerNonKeepStepクラス判定
962 //----------------------------------------------------------------------------
963 
964 template<class tClass, class tEnable=void>
965 struct IsTheolizerNonKeepStepImpl : public std::false_type
966 { };
967 
968 template<class tClass>
969 struct IsTheolizerNonKeepStepImpl
970 <
971  tClass,
972  EnableIf<tClass::kIsTheolizerNonKeepStep>
973 > : public std::true_type
974 { };
975 
976 template<class tClass>
977 struct IsTheolizerNonKeepStep
978 {
979  static const bool value=IsTheolizerNonKeepStepImpl<tClass>::value;
980 };
981 
982 //----------------------------------------------------------------------------
983 // 非侵入型クラス判定
984 //----------------------------------------------------------------------------
985 
986 template<class tClass, class tEnable=void>
987 struct IsNonIntrusiveImpl : public std::false_type
988 { };
989 
990 template<class tClass>
991 struct IsNonIntrusiveImpl
992 <
993  tClass,
994  EnableIf
995  <
996  TheolizerNonIntrusive<typename std::remove_const<tClass>::type>::kIsTheolizer
997  >
998 > : public std::true_type
999 { };
1000 
1001 template<class tClass>
1002 struct IsNonIntrusive
1003 {
1004  static const bool value=IsNonIntrusiveImpl<tClass>::value;
1005 };
1006 
1007 //----------------------------------------------------------------------------
1008 // 侵入型判定
1009 //----------------------------------------------------------------------------
1010 
1011 template<class tClass, class tEnable=void>
1012 struct IsIntrusiveImpl : public std::false_type
1013 { };
1014 
1015 template<class tClass>
1016 struct IsIntrusiveImpl
1017 <
1018  tClass,
1019  EnableIf
1020  <
1021  std::is_class<tClass>::value
1022  && !IsString<tClass>::value
1023  && !IsNonIntrusive<tClass>::value
1024  && !IsTheolizerBase<tClass>::value
1025  && !IsTheolizerNonKeepStep<tClass>::value
1026  >
1027 > : public std::true_type
1028 { };
1029 
1030 template<class tClass>
1031 struct IsIntrusive
1032 {
1033  static const bool value=IsIntrusiveImpl<tClass>::value;
1034 };
1035 
1036 //----------------------------------------------------------------------------
1037 // バージョンアップで削除された領域管理用クラス
1038 // 定義された時点では領域を確保せず、get()の時点で確保する。
1039 // 領域をポインタで確保するのでTheolizerSpecials<>をムーブ対応
1040 // できるようになる。
1041 // ムーブ可能/コピー不可
1042 //----------------------------------------------------------------------------
1043 
1044 // ---<<< deleteツール >>>---
1045 // 配列への参照メンバはTypeが配列への参照となる。
1046 // その時、Typeは単なる配列なので、delete[]する。
1047 
1048 template<typename tType, class tEnable=void>
1049 struct Deleter
1050 {
1051  static void deleteMember(tType* iData)
1052  {
1053  delete iData;
1054  }
1055 };
1056 
1057 template<typename tType>
1058 struct Deleter<tType, EnableIf<std::is_array<tType>::value> >
1059 {
1060  static void deleteMember(tType* iData)
1061  {
1062  delete[] iData;
1063  }
1064 };
1065 
1066 // ---<<< 本体 >>>---
1067 
1068 template<typename tType>
1069 class DeferredGeneration
1070 {
1071 private:
1072  typedef typename std::remove_reference<tType>::type Type;
1073 
1074  Type* mData;
1075 
1076 public:
1077  DeferredGeneration() : mData(nullptr) { }
1078  ~DeferredGeneration()
1079  {
1080  Deleter<Type>::deleteMember(mData);
1081  }
1082 
1083  // 領域獲得
1084  Type& get()
1085  {
1086  if (!mData)
1087  {
1088  // (配列型へのポインタに対応するためreinterpret_castする)
1089  mData=reinterpret_cast<tType*>(new Type());
1090  }
1091  return *mData;
1092  }
1093 
1094  // ムーブ
1095  DeferredGeneration(DeferredGeneration&& ioDeferredGeneration) noexcept :
1096  mData(ioDeferredGeneration.mData)
1097  {
1098  ioDeferredGeneration.mData=nullptr;
1099  }
1100  DeferredGeneration& operator=(DeferredGeneration&& ioDeferredGeneration)
1101  {
1102  mData=ioDeferredGeneration.mData;
1103  ioDeferredGeneration.mData=nullptr;
1104  }
1105 
1106  // コピー可
1107  DeferredGeneration(DeferredGeneration const& iRhs)
1108  {
1109  mData=iRhs.mData;
1110  }
1111  DeferredGeneration& operator=(DeferredGeneration const& iRhs)
1112  {
1113  mData=iRhs.mData;
1114  return *this;
1115  }
1116 };
1117 
1118 #define THEOLIZER_INTERNAL_DEFERRED_GENERATION(dType) \
1119  theolizer::internal::DeferredGeneration<THEOLIZER_INTERNAL_UNPAREN dType>
1120 
1121 // ***************************************************************************
1122 // 型情報取得中継
1123 // ***************************************************************************
1124 
1125 //----------------------------------------------------------------------------
1126 // 基底クラス
1127 //----------------------------------------------------------------------------
1128 
1129 class BaseTypeFunctions;
1130 THEOLIZER_INTERNAL_DLL BaseTypeFunctions* getTypeFunctions();
1131 THEOLIZER_INTERNAL_DLL void setTypeFunctions(BaseTypeFunctions* iTypeFunctions);
1132 
1133 class BaseTypeFunctions
1134 {
1135 public:
1136  static BaseTypeFunctions const& getInstance()
1137  {
1138  BaseTypeFunctions* ret=getTypeFunctions();
1139  if (!ret)
1140  {
1141  THEOLIZER_INTERNAL_ERROR(u8"BaseTypeFunctions is null.");
1142  }
1143  return *ret;
1144  }
1145 
1146  #define THEOLIZER_INTERNAL_DEF_PRIMITIVE(dType, dSimbol) \
1147  virtual char const* getPrimitiveName(unsigned iSerializerVersionNo, dType) const=0;
1148 
1149  #define THEOLIZER_INTERNAL_DEF_STRING(dType, dSimbol) \
1150  virtual char const* getPrimitiveName(unsigned iSerializerVersionNo, dType const&) const=0;
1151 
1152  #include "primitive.inc"
1153 
1154  virtual std::type_index getStdTypeIndex() const=0;
1155  virtual unsigned getLastVersionNo() const=0;
1156  virtual char const* getSerializerName() const=0;
1157 
1158 #ifdef THEOLIZER_INTERNAL_ENABLE_META_SERIALIZER
1159  virtual char const* getCppName
1160  (
1161  std::string const& iPrimitiveName,
1162  unsigned iSerializerVersionNo
1163  ) const=0;
1164 #endif // THEOLIZER_INTERNAL_ENABLE_META_SERIALIZER
1165 };
1166 
1167 //----------------------------------------------------------------------------
1168 // 現在有効な派生Serializer
1169 //----------------------------------------------------------------------------
1170 
1171 template<class tMidSerializer>
1172 class TypeFunctions : public BaseTypeFunctions
1173 {
1174  BaseTypeFunctions* mBackup;
1175 public:
1176  // 登録
1177  TypeFunctions()
1178  {
1179  mBackup=getTypeFunctions();
1180  setTypeFunctions(this);
1181  }
1182  // 解除
1183  ~TypeFunctions()
1184  {
1185  setTypeFunctions(mBackup);
1186  }
1187 
1188  #define THEOLIZER_INTERNAL_DEF_PRIMITIVE(dType, dSimbol) \
1189  char const* getPrimitiveName(unsigned iSerializerVersionNo, dType) const\
1190  { \
1191  return tMidSerializer::template getPrimitiveName<dType>(iSerializerVersionNo);\
1192  }
1193  #define THEOLIZER_INTERNAL_DEF_STRING(dType, dSimbol) \
1194  char const* getPrimitiveName(unsigned iSerializerVersionNo, dType const&) const\
1195  { \
1196  return tMidSerializer::template getPrimitiveName<dType>(iSerializerVersionNo);\
1197  }
1198 
1199  #include "primitive.inc"
1200 
1201  std::type_index getStdTypeIndex() const {return std::type_index(typeid(tMidSerializer));}
1202  unsigned getLastVersionNo() const {return tMidSerializer::kLastVersionNo;}
1203  char const* getSerializerName() const {return tMidSerializer::kSerializerName;}
1204 
1205 #ifdef THEOLIZER_INTERNAL_ENABLE_META_SERIALIZER
1206  char const* getCppName
1207  (
1208  std::string const& iPrimitiveName,
1209  unsigned iSerializerVersionNo
1210  ) const
1211  {
1212  return tMidSerializer::getCppName(iPrimitiveName, iSerializerVersionNo);
1213  }
1214 #endif // THEOLIZER_INTERNAL_ENABLE_META_SERIALIZER
1215 };
1216 
1217 #endif // THEOLIZER_INTERNAL_DOXYGEN
1218 } // namespace internal
1219 
1220 } // namespace theolizer
1221 
1222 //############################################################################
1223 // End
1224 //############################################################################
1225 
1226 // ***************************************************************************
1227 // 警告抑止解除
1228 // ***************************************************************************
1229 
1230 #ifdef _MSC_VER
1231  #pragma warning(pop)
1232 #endif
1233 
1234 #endif // THEOLIZER_INTERNAL_CORE_ASSORTED_H
CheckMode
型チェック・モード
theolizer名前空間
Definition: base.h:53
TypeIndexによる型チェック
auto getRBForIndexer(tContainer &&iContainer, tNextFunc &&iNextFunc=internal::NopFunctor()) -> typename internal::MakeRBForAdaptor< internal::Indexer, tContainer, tNextFunc >::Type
範囲ベースforを分割できるようにし、かつ、インデックス番号用レンジ生成
Definition: rbfor.h:339
型チェック無し
Destination
保存先シンボルを定義するscoped enum型
THEOLIZER_INTERNAL_DLL std::ostream & operator<<(std::ostream &iOStream, CheckMode iCheckMode)
CheckModeの表示用オーバーロード
Property
シリアライザが提供する機能(プロパティ)のリスト
型名による型チェック