Theolizer  Version.1.2.0
serializer for C++ / Do you want to update your classes easily ?
core_serializer.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_CORE_SERIALIZER_H)
32 #define THEOLIZER_INTERNAL_CORE_SERIALIZER_H
33 
34 #include "core_type_info.h"
35 #include "version_array.h"
36 
37 //############################################################################
38 // Begin
39 //############################################################################
40 
41 // ***************************************************************************
42 // 警告抑止
43 // ***************************************************************************
44 
45 #ifdef _MSC_VER
46  #pragma warning(push)
47  #pragma warning(disable:4100 4127 4251)
48 #endif
49 
50 namespace theolizer
51 {
52 namespace internal
53 {
54 #ifndef THEOLIZER_INTERNAL_DOXYGEN
55 
56 //############################################################################
57 // シリアライズ用内部処理マクロ
58 //############################################################################
59 
60 // ***************************************************************************
61 // 非侵入型(完全自動)のノーマル >>>---
62 // 対応方法=フィールド名
63 // ***************************************************************************
64 
65 #define THEOLIZER_INTERNAL_NON_INTRUSIVE(dClass) \
66  template<> \
67  struct TheolizerNonIntrusive<dClass> : public dClass \
68  { \
69  THEOLIZER_INTERNAL_SERIALIZABLE_AUTO(, \
70  (TheolizerNonIntrusive<dClass>), (dClass), 1, \
71  (), theolizer::internal::emName, true, true); \
72  }
73 
74 // ---<<<< 非侵入型(完全自動)のテンプレート >>>---
75 // 対応方法=フィールド名
76 
77 #define THEOLIZER_INTERNAL_NON_INTRUSIVE_TEMPLATE(dList, dClass, dUniqueClass)\
78  THEOLIZER_INTERNAL_UNPAREN dList \
79  struct TheolizerNonIntrusive<THEOLIZER_INTERNAL_UNPAREN dClass> : \
80  public THEOLIZER_INTERNAL_UNPAREN dClass \
81  { \
82  THEOLIZER_ANNOTATE( \
83  TS:THEOLIZER_INTERNAL_UNPAREN dList;THEOLIZER_INTERNAL_UNPAREN dClass)\
84  THEOLIZER_INTERNAL_SERIALIZABLE_AUTO(, \
85  (TheolizerNonIntrusive<THEOLIZER_INTERNAL_UNPAREN dClass>), dClass, 1,\
86  (friend struct dUniqueClass;), theolizer::internal::emName, true, true);\
87  }
88 
89 //----------------------------------------------------------------------------
90 // サブマクロ
91 // クラス・テンプレートにおいて
92 // Theilizerライブラリでは、struct DefineUniqueName;にて
93 // グローバル・バージョン番号テーブルと自クラスをバインドする
94 // Theilizerドライバでは、friend struct dUniqueClass;にて
95 // TheolizerVersion<>と自クラスをバインドする
96 // 自クラスとは、
97 // 侵入型は、 ターゲット・クラス
98 // 非侵入型は TheolizerNonIntrusive<ターゲット・クラス>
99 //----------------------------------------------------------------------------
100 
101 #define THEOLIZER_INTERNAL_SERIALIZABLE() \
102  static const bool kIsTheolizer=true; \
103  template<class> friend struct theolizer::internal::IsTheolizerNonKeepStep;\
104  template<class, class> friend struct theolizer::internal::IsTheolizerNonKeepStepImpl;\
105  template<class, typename, bool, theolizer::internal::TrackingMode, class>\
106  friend struct theolizer::internal::Switcher; \
107  template<typename, bool> friend struct theolizer::internal::RegisterToBaseClassEntrance;\
108  template<class> friend class theolizer::internal::ClassTypeInfo
109 
110 #define THEOLIZER_INTERNAL_SERIALIZABLE_AUTO(dAttribute, dClass, dTarget, dLastVersionNo,\
111  dDefineUnique, dMap, dIsNonIntrusive, dIsFullAuto)\
112  typedef THEOLIZER_INTERNAL_UNPAREN dTarget TheolizerTarget; \
113  dAttribute \
114  typedef THEOLIZER_INTERNAL_UNPAREN dClass TheolizerClass; \
115  struct Theolizer \
116  { \
117  THEOLIZER_INTERNAL_UNPAREN dDefineUnique \
118  static const bool kIsFullAuto=dIsFullAuto; \
119  static const unsigned kLastVersionNo=dLastVersionNo; \
120  static const theolizer::internal::ElementsMapping kElementsMapping=dMap;\
121  struct DefineUniqueName; \
122  \
123  static const bool kIsNonIntrusive=dIsNonIntrusive; \
124  static const bool kIsAuto=true; \
125  static const bool kIsVersion=false; \
126  \
127  static std::string getClassName( \
128  theolizer::internal::VersionNoList const&, unsigned); \
129  static char const* getUniqueName(); \
130  static theolizer::internal::ElementsMapping getElementsMapping(unsigned);\
131  static theolizer::internal::ElementRange getElementRange(unsigned); \
132  static unsigned getTypeFlags(unsigned); \
133  static void registerToBaseClass(theolizer::internal::BaseTypeInfo*);\
134  \
135  static void saveClass(theolizer::internal::BaseSerializer&, \
136  TheolizerClass*&, unsigned); \
137  static void loadClass(theolizer::internal::BaseSerializer&, \
138  TheolizerClass*&, unsigned); \
139  }; \
140  template<class tTheolizerVersion, class tNextVersion, unsigned tVersionNo>\
141  struct TheolizerUserDefine \
142  { \
143  static const unsigned kTheolizerVersionNo=tVersionNo; \
144  static void downVersion(tNextVersion const&, tTheolizerVersion&) { }\
145  static void upVersion(tTheolizerVersion const&, tNextVersion&) { } \
146  }; \
147  template<class tBaseSerializer, unsigned tVersionNo> \
148  struct TheolizerSpecials { }; \
149  THEOLIZER_INTERNAL_SERIALIZABLE(); \
150 public: \
151  template<class tBaseSerializer, unsigned tVersionNo> \
152  struct TheolizerVersion { }
153 
154 #define THEOLIZER_INTERNAL_SERIALIZABLE_MANUAL(dClass, dLastVersionNo, \
155  dDefineUnique, dMap, dIsNonIntrusive)\
156  typedef THEOLIZER_INTERNAL_UNPAREN dClass TheolizerTarget; \
157  typedef TheolizerNonIntrusive<THEOLIZER_INTERNAL_UNPAREN dClass> TheolizerClass;\
158  struct Theolizer \
159  { \
160  THEOLIZER_INTERNAL_UNPAREN dDefineUnique \
161  static const bool kIsFullAuto=false; \
162  static const unsigned kLastVersionNo=dLastVersionNo; \
163  static const theolizer::internal::ElementsMapping kElementsMapping=dMap;\
164  struct DefineUniqueName; \
165  \
166  static const bool kIsNonIntrusive=dIsNonIntrusive; \
167  static const bool kIsAuto=false; \
168  static const bool kIsVersion=false; \
169  \
170  static std::string getClassName( \
171  theolizer::internal::VersionNoList const&, unsigned); \
172  static char const* getUniqueName(); \
173  static theolizer::internal::ElementsMapping getElementsMapping(unsigned);\
174  static theolizer::internal::ElementRange getElementRange(unsigned); \
175  static unsigned getTypeFlags(unsigned) {return 0;} \
176  static void registerToBaseClass(theolizer::internal::BaseTypeInfo*);\
177  \
178  static void saveClass(theolizer::internal::BaseSerializer&, \
179  TheolizerClass*&, unsigned); \
180  static void loadClass(theolizer::internal::BaseSerializer&, \
181  TheolizerClass*&, unsigned); \
182  }; \
183  template<class tBaseSerializer, class tTheolizerVersion, unsigned tVersionNo>\
184  struct TheolizerUserDefine \
185  { \
186  static const unsigned kTheolizerVersionNo=tVersionNo; \
187  static void saveClassManual \
188  (tBaseSerializer&, typename tTheolizerVersion::TheolizerTarget const*const&)\
189  { \
190  static_assert(theolizer::internal::Ignore<tBaseSerializer>::kFalse,\
191  "saveClassManual() is undefined"); \
192  } \
193  static void loadClassManual \
194  (tBaseSerializer&, typename tTheolizerVersion::TheolizerClass*&)\
195  { \
196  static_assert(theolizer::internal::Ignore<tBaseSerializer>::kFalse,\
197  "loadClassManual() is undefined"); \
198  } \
199  }; \
200  THEOLIZER_INTERNAL_SERIALIZABLE(); \
201 public: \
202  template<class tBaseSerializer, unsigned tVersionNo> \
203  struct TheolizerVersion { }
204 
205 #define THEOLIZER_INTERNAL_TEMPLATE_PARAMETER(dClass, dName, dParam, dUniqueClass)\
206  typedef void NoGenerate; /* ドライバへの自動生成無し指示 */ \
207  typedef THEOLIZER_INTERNAL_UNPAREN dClass TheolizerTarget; \
208  typedef TheolizerNonIntrusive<THEOLIZER_INTERNAL_UNPAREN dClass> TheolizerClass;\
209  struct Theolizer \
210  { \
211  friend struct dUniqueClass; \
212  static const bool kIsFullAuto=false; \
213  static const unsigned kLastVersionNo=1; \
214  static const theolizer::internal::ElementsMapping kElementsMapping= \
215  theolizer::internal::emOrder; \
216  struct DefineUniqueName {typedef dUniqueClass UniqueClass;}; \
217  static const bool kIsNonIntrusive=true; \
218  static const bool kIsAuto=false; \
219  static const bool kIsVersion=false; \
220  \
221  static std::string getClassName( \
222  theolizer::internal::VersionNoList const& iVersionNoList, unsigned)\
223  {return THEOLIZER_INTERNAL_MAKE_TEMPLATE_NAME( \
224  u8"" #dName,THEOLIZER_INTERNAL_UNPAREN dParam);} \
225  static char const* getUniqueName() {return #dUniqueClass;} \
226  static theolizer::internal::ElementsMapping getElementsMapping(unsigned)\
227  {return kElementsMapping;} \
228  static theolizer::internal::ElementRange getElementRange(unsigned) \
229  {return theolizer::internal::ElementRange();} \
230  static unsigned getTypeFlags(unsigned) {return 0;} \
231  \
232  static void saveClass(theolizer::internal::BaseSerializer&,TheolizerClass*&, unsigned)\
233  {THEOLIZER_INTERNAL_ABORT("use THEOLIZER_NON_INTRUSIVE_XXX, if serialize this class.");}\
234  static void loadClass(theolizer::internal::BaseSerializer&,TheolizerClass*&, unsigned)\
235  {THEOLIZER_INTERNAL_ABORT("use THEOLIZER_NON_INTRUSIVE_XXX, if serialize this class.");}\
236  }; \
237  template<class tBaseSerializer, class tTheolizerVersion, unsigned tVersionNo>\
238  struct TheolizerUserDefine \
239  { \
240  static const unsigned kTheolizerVersionNo=tVersionNo; \
241  static void saveClassManual \
242  (tBaseSerializer&, typename tTheolizerVersion::TheolizerTarget const*const&)\
243  { } \
244  static void loadClassManual \
245  (tBaseSerializer&, typename tTheolizerVersion::TheolizerClass*&)\
246  { } \
247  }; \
248  THEOLIZER_INTERNAL_SERIALIZABLE()
249 
250 // ***************************************************************************
251 // enum型のシリアライズ指定
252 // ***************************************************************************
253 
254 //----------------------------------------------------------------------------
255 // 内部処理用マクロとstaticクラス
256 //----------------------------------------------------------------------------
257 
258 #define THEOLIZER_INTERNAL_ENUM_FULL_AUTO(dEnum) \
259  THEOLIZER_INTERNAL_ENUM(dEnum, 1, theolizer::internal::estName, true)
260 
261 #define THEOLIZER_INTERNAL_ENUM(dEnum, dLastVersionNo, dEnumSaveType, dIsFullAuto)\
262  template<> \
263  struct TheolizerNonIntrusive<dEnum> \
264  { \
265  typedef dEnum TheolizerTarget; \
266  struct Theolizer \
267  { \
268  static const bool kIsFullAuto=dIsFullAuto; \
269  static const unsigned kVersionNo=dLastVersionNo; \
270  static const unsigned kLastVersionNo=dLastVersionNo; \
271  static const theolizer::internal::EnumSaveType kEnumSaveType=dEnumSaveType;\
272  static const bool kIsNonIntrusive=true; \
273  \
274  static char const* getEnumName(unsigned iVersionNo); \
275  static unsigned getTypeFlags(unsigned); \
276  static theolizer::internal::ElementRange getElementRange(unsigned);\
277  \
278  static void saveEnum(theolizer::internal::BaseSerializer& iSerializer,\
279  dEnum& iInstance, unsigned iVersionNo); \
280  static void loadEnum(theolizer::internal::BaseSerializer& iSerializer,\
281  dEnum& iInstance, unsigned iVersionNo); \
282  }; \
283  typedef TheolizerNonIntrusive<dEnum> TheolizerClass; \
284  template<class tBaseSerializer, unsigned tVersionNo> \
285  struct TheolizerVersion { }; \
286  }
287 
288 // ***************************************************************************
289 // トップ・レベルのシリアライズ/デシリアライズ処理
290 // ***************************************************************************
291 
292 //----------------------------------------------------------------------------
293 // 補助マクロ
294 // 下記状況が発生するケースがあるので、その対処
295 // MinGWではtypename/templateが必要
296 // msvc ではtypename/tempalteががあるとエラー
297 //----------------------------------------------------------------------------
298 
299 #if defined(_MSC_VER) && !defined(__clang__)
300  #define THEOLIZER_INTERNAL_TYPENAME
301  #define THEOLIZER_INTERNAL_TEMPLATE
302 #else
303  #define THEOLIZER_INTERNAL_TYPENAME typename
304  #define THEOLIZER_INTERNAL_TEMPLATE template
305 #endif
306 
307 //----------------------------------------------------------------------------
308 // 内部処理用マクロ(TheolizerVersion<>内部からの呼び出しのみ)
309 // dInstanceは参照なので、remove_referenceする。
310 //----------------------------------------------------------------------------
311 
312 // ---<<< 内部用保存処理(事前処理無し・参照解除・保存エラー無し) >>>---
313 
314 #define THEOLIZER_INTERNAL_SAVE(dMidSerializer, dInstance, dTrackingMode) \
315  do { \
316  THEOLIZER_INTERNAL_SETUP(dMidSerializer, dInstance); \
317  theolizer::internal::Switcher< \
318  Serializer, Type, true, theolizer::internal::dTrackingMode \
319  >::save(dMidSerializer, dInstance); \
320  } while(0)
321 
322 // ---<<< 内部用回復処理(事前処理無し・参照解除・回復エラー無し) >>>---
323 
324 #define THEOLIZER_INTERNAL_LOAD(dMidSerializer, dInstance, dTrackingMode) \
325  do { \
326  THEOLIZER_INTERNAL_SETUP(dMidSerializer, dInstance); \
327  theolizer::internal::Switcher< \
328  Serializer, Type, true, theolizer::internal::dTrackingMode \
329  >::load(dMidSerializer, dInstance); \
330  } while(0)
331 
332 // ---<<< 型取出し >>>---
333 
334 #define THEOLIZER_INTERNAL_SETUP(dSerializer, dInstance) \
335  typedef THEOLIZER_INTERNAL_TYPENAME \
336  std::remove_reference<decltype(dSerializer)>::type Serializer; \
337  typedef decltype(dInstance) TypeTemp; \
338  typedef THEOLIZER_INTERNAL_TYPENAME std::remove_reference<TypeTemp>::type Type;\
339  typedef THEOLIZER_INTERNAL_TYPENAME std::remove_pointer<Type>::type TypeRemoved;\
340  static_assert(!std::is_pointer<TypeRemoved>::value, "Not support Pointer to Pointer.")
341 
342 //############################################################################
343 // エラー報告サービス群
344 //############################################################################
345 
346 // ***************************************************************************
347 // シリアライズ状況管理
348 // ***************************************************************************
349 
350 //----------------------------------------------------------------------------
351 // シリアライズ状況クラス
352 //----------------------------------------------------------------------------
353 
354 class BaseSerializer;
355 
356 class THEOLIZER_INTERNAL_DLL AdditionalInfo : public BaseAdditionalInfo
357 {
358  // 付加情報記録領域(ヘッダ依存回避)
359  struct Indep;
360  std::unique_ptr<Indep> mIndep;
361 
362  // setErrorによるエラー報告先(基底Serializer)
363  BaseSerializer& mBaseSerializer;
364 
365 public:
366  // コンストラクタ/デストラクタ
367  AdditionalInfo(BaseSerializer& iBaseSerializer) noexcept;
368  ~AdditionalInfo() noexcept;
369 
370  // インスタンス情報登録/解除
371  void pushInstanceInfo
372  (
373  char const* iName,
374  size_t iIndex=0,
375  bool iIsPointer=false,
376  char const* iFileName=nullptr,
377  size_t iLineNo=0
378  );
379  void popInstanceInfo();
380 
381  // メッセージ取り出し
382  u8string getString();
383 
384  // エラー情報伝達
385  void setError(ErrorInfo const& iErrorInfo, bool iConstructor);
386 };
387 
388 //############################################################################
389 // 構造処理
390 // xml生成時に用いている。
391 //############################################################################
392 
393 // ***************************************************************************
394 // 構造を示すenum型
395 // ***************************************************************************
396 
397 enum class Structure
398 {
399  None,
400  Class,
401  Pointee,
402  Array,
403  Pointer,
404  OwnerPointer,
405  Reference // 参照による動的ポリモーフィズム処理用
406 };
407 
408 //############################################################################
409 // オブジェクト追跡用クラス
410 //############################################################################
411 
412 // ***************************************************************************
413 // オブジェクトの追跡状態
414 // ***************************************************************************
415 
416 enum TrackingStatus
417 {
418  etsInit, // 初期状態
419  etsNullPtr, // 全てのnullptrのための追跡状態
420  etsPointed, // 対象領域へのポインタ処理済(データは未処理)
421  etsProcessed // 対象領域のデータの処理(保存/回復)済
422 };
423 
424 // ***************************************************************************
425 // シリアライズ用オブジェクト情報
426 // ***************************************************************************
427 
428 struct SerializeInfo
429 {
430  size_t mObjectId;
431  TrackingStatus mStatus;
432 
433  SerializeInfo() :
434  mObjectId(0),
435  mStatus(etsInit)
436  { }
437 
438  SerializeInfo
439  (
440  size_t iObjectId,
441  TrackingStatus iStatus
442  ) : mObjectId(iObjectId),
443  mStatus(iStatus)
444  { }
445 };
446 
447 // ***************************************************************************
448 // デシリアライズ用オブジェクト情報
449 // ***************************************************************************
450 
451 struct DeserializeInfo
452 {
453  void* mAddress;
454  TrackingStatus mStatus;
455 
456  DeserializeInfo() :
457  mAddress(nullptr),
458  mStatus(etsInit)
459  { }
460 };
461 
462 // ***************************************************************************
463 // shared_ptrデシリアライズ時の共有判定用テーブル
464 // std::shared_ptr<>に用いるが、他の形式の共有ポインタにも使用できるよう
465 // テーブルの構造は使う側に任せるので、boost::any方式とする。
466 // ***************************************************************************
467 
468 struct SharedPtrTable
469 {
470 
471 // ---<<< 記録用内部クラスの基底型 >>>---
472 
473  struct HolderBase
474  {
475  virtual void clear() = 0;
476  virtual ~HolderBase() { }
477  };
478 
479 // ---<<< 記録用内部クラス >>>---
480 
481  template<typename tListType>
482  struct Holder : public HolderBase
483  {
484  tListType mList;
485 
486  Holder() { }
487  ~Holder() = default;
488 
489  virtual void clear()
490  {
491  mList.clear();
492  }
493  };
494 
495 // ---<<< 記録領域 >>>---
496 
497  std::unique_ptr<HolderBase> mHolder;
498 
499 // ---<<< コンストラクタ >>>---
500 
501  SharedPtrTable() { }
502 
503  // 登録をクリアする
504  void clear()
505  {
506  mHolder->clear();
507  }
508 };
509 
510 //############################################################################
511 // Serializer用フレンド・リスト
512 //############################################################################
513 
514 // theolizer::internal名前空間のクラスにて使用する
515 #define THEOLIZER_INTERNAL_FRIENDS_FOR_INTERNAL \
516  template<TrackingMode, class, class, typename, class> friend struct BranchedProcess; \
517  template<TrackingMode, class, class tSerializer, typename tType> \
518  friend void process(tSerializer&, tType const&, char const*, char const*, size_t); \
519  template<TrackingMode, class, class tSerializer, typename tType> \
520  friend void process(tSerializer&, tType&, char const*, char const*, size_t); \
521  template<typename> friend class ArrayTypeInfo; \
522  template<typename> friend class ClassTypeInfo; \
523  template<typename> friend class EnumTypeInfo; \
524  template<typename> friend class PrimitiveTypeInfo;\
525  template<class, typename, bool, TrackingMode, class> friend struct Switcher; \
526  template<class, typename, class> friend struct SavePointer; \
527  template<class, typename, class> friend struct LoadPointer; \
528  template<typename...> friend struct ParameterName; \
529  template<class> friend struct ::TheolizerNonIntrusive; \
530  template<class, class> friend struct ::TheolizerNonKeepStep; \
531  template<class> friend class TypeFunctions; \
532  template<class, class, class, bool, bool> friend class RegisterType; \
533  friend class BaseTypeInfo; \
534  template<typename> friend class Element; \
535  template<typename> friend struct EnumElement; \
536  friend struct MetaDeserializer; \
537  friend class AdditionalInfo; \
538  friend class AutoRestoreIsShared
539 
540 // theolizer名前空間のクラスにて使用する
541 #define THEOLIZER_INTERNAL_FRIENDS \
542  template<internal::TrackingMode, class, class, typename, class> \
543  friend struct internal::BranchedProcess; \
544  template<internal::TrackingMode, class, class tSerializer, typename tType> \
545  friend void internal::process(tSerializer&,tType const&,char const*,char const*,size_t);\
546  template<internal::TrackingMode, class, class tSerializer, typename tType> \
547  friend void internal::process(tSerializer&,tType&,char const*,char const*,size_t); \
548  template<class> friend class internal::TypeFunctions; \
549  template<class, class, class, bool, bool> friend class internal::RegisterType; \
550  template<class> friend int internal::registerMidSerializer()
551 
552 #endif // THEOLIZER_INTERNAL_DOXYGEN
553 //############################################################################
554 /*!
555  @brief 基底Serializer
556  @details 各シリアライザがprotected継承する<br>
557 */
558 //############################################################################
559 
560 class THEOLIZER_INTERNAL_DLL BaseSerializer : public ErrorBase
561 {
562 // ***************************************************************************
563 // 基本
564 // ***************************************************************************
565 
566 private:
567  THEOLIZER_INTERNAL_FRIENDS_FOR_INTERNAL;
568 
569  virtual void AbstructSerializer() = 0; // インスタンス生成禁止
570 
571  BaseSerializer* mSerializerBack; // 前回処理中のSerializer(退避領域)
572 
573 protected:
574  Destinations const& mDestinations;
575  bool mIsSaver;
576  bool mNoThrowException;
577 
578  GlobalVersionNoTableBase const*const mGlobalVersionNoTable;
579  unsigned mGlobalVersionNo;
580  unsigned mLastGlobalVersionNo;
581  TypeInfoListImpl& mTypeInfoList;
582 
583 private:
584  size_t mTypeIndexCount;
585  bool mRequireClearTracking;
586 
587 public:
588 #ifndef THEOLIZER_INTERNAL_DOXYGEN
589  // デフォルトは保存先無し
590  static const bool kHasDestination=false;
591 #endif // THEOLIZER_INTERNAL_DOXYGEN
592 
593  //! std::stringをマルチ・パイト文字コードとして処理することを指定する(NOP)
594  virtual void setCharIsMultiByte(bool) { }
595 
596 protected:
597  //! clearTracking()が必要な時true返却(@ref MemberFunctions 参照)
598  bool getRequireClearTracking() { return mRequireClearTracking; }
599 
600  // RegisterTypeコンストラクト時の余分なstruct定義回避
601  constexpr static GlobalVersionNoTableBase const*const*const
602  kPtrGlobalVersionNoTable=nullptr;
603  static internal::Destinations getDestinations()
604  {
605  return internal::Destinations{};
606  }
607 
609  (
610  Destinations const& iDestinations,
611  GlobalVersionNoTableBase const*const iGlobalVersionNoTable,
612  unsigned iGlobalVersionNo,
613  unsigned iLastGlobalVersionNo,
614  CheckMode iCheckMode,
615  bool iIsSaver,
616  std::ostream* iOStream,
617  bool mNoThrowException
618  );
619  virtual ~BaseSerializer() noexcept;
620 
621  // コピー禁止
622  BaseSerializer(const BaseSerializer&) = delete;
623  BaseSerializer& operator=(const BaseSerializer&) = delete;
624 
625 // ***************************************************************************
626 // シリアライズ/デシリアライズ補助API
627 // ***************************************************************************
628 
629 public:
630  //! 処理中のグローバル・バージョン番号返却(@ref MemberFunctions 参照)
631  unsigned getGlobalVersionNo() const {return mGlobalVersionNo;}
632 
633 // ***************************************************************************
634 // エラー処理用
635 // ***************************************************************************
636 
637 private:
638  using ErrorBase::setError; // ErrorBaseにAdditionalInfoをfriend指定したくないので
639 
640 // ---<<< シリアライズ情報管理 >>>---
641 
642 protected:
643  AdditionalInfo mAdditionalInfo;
644 
645 // ---<<< 変数パスのpush/自動pop用 >>>---
646 
647  struct AutoRestoreSerializeInfo
648  {
649  AdditionalInfo& mAdditionalInfo;
650 
651  AutoRestoreSerializeInfo
652  (
653  BaseSerializer& iSerializer,
654  char const* iName,
655  size_t iIndex=0,
656  bool iIsPointer=false,
657  char const* iFileName=nullptr,
658  size_t iLineNo=0
659  ) noexcept : mAdditionalInfo(iSerializer.mAdditionalInfo)
660  {
661  mAdditionalInfo.pushInstanceInfo(iName, iIndex, iIsPointer, iFileName, iLineNo);
662  }
663  ~AutoRestoreSerializeInfo() noexcept
664  {
665  mAdditionalInfo.popInstanceInfo();
666  }
667  };
668 
669  // 例外許可獲得
670  bool getNoThrowException() const {return mNoThrowException;}
671 
672  // プリミティブ処理後のエラー・チェック
673  void checkStreamError(std::ios::iostate iIoState);
674 
675 // ***************************************************************************
676 // オブジェクト・トラッキング処理
677 // ***************************************************************************
678 
679 //----------------------------------------------------------------------------
680 // クラス・インスンタスについてオブジェクト追跡中の管理
681 // そのクラスの基底クラスについてもオブジェクト追跡を行うために用いる
682 //----------------------------------------------------------------------------
683 
684 private:
685  // 派生クラスの一部としての基底クラス処理中
686  bool mBaseProcessing;
687  struct AutoBaseProcessing
688  {
689  bool mBaseProcessingBack;
690  bool& mBaseProcessing;
691  AutoBaseProcessing(BaseSerializer& iSerializer) :
692  mBaseProcessingBack(iSerializer.mBaseProcessing),
693  mBaseProcessing( iSerializer.mBaseProcessing)
694  {
695  mBaseProcessing=true;
696  }
697  ~AutoBaseProcessing()
698  {
699  mBaseProcessing=mBaseProcessingBack;
700  }
701  };
702 
703  // クラスのオブジェクト追跡中
704  bool mClassTracking;
705  struct AutoClassTracking
706  {
707  bool mClassTrackingBack;
708  bool& mClassTracking;
709  AutoClassTracking(BaseSerializer& iSerializer) :
710  mClassTrackingBack(iSerializer.mClassTracking),
711  mClassTracking( iSerializer.mClassTracking)
712  {
713  mClassTracking=true;
714  }
715  ~AutoClassTracking()
716  {
717  mClassTracking=mClassTrackingBack;
718  }
719  };
720 
721  // 参照処理中
722  bool mRefProcessing;
723  struct AutoRefProcessing
724  {
725  bool mRefProcessingBack;
726  bool& mRefProcessing;
727  AutoRefProcessing(BaseSerializer& iSerializer) :
728  mRefProcessingBack(iSerializer.mRefProcessing),
729  mRefProcessing( iSerializer.mRefProcessing)
730  {
731  mRefProcessing=true;
732  }
733  ~AutoRefProcessing()
734  {
735  mRefProcessing=mRefProcessingBack;
736  }
737  };
738 
739 
740 //----------------------------------------------------------------------------
741 // オブジェクト追跡テーブルをクリアする
742 // 追跡テーブルに登録されている領域は、2回目以降、保存/回復されない。
743 // 追跡テーブルをクリアすることで、保存/回復するようになる。
744 // 同時に未解決の追跡情報が残っていないかもチェックし、不正なら例外
745 //----------------------------------------------------------------------------
746 
747 private:
748  void clearTrackingImpl();
749 
750 public:
751  //! オブジェクト追跡の区切り(@ref MemberFunctions 参照)
752  void clearTracking();
753 
754 //----------------------------------------------------------------------------
755 // SharedPtrTable登録テーブル
756 //----------------------------------------------------------------------------
757 
758 private:
759  struct SharedPtrTables;
760  std::unique_ptr<SharedPtrTables> mSharedPtrTables;
761 
762  SharedPtrTable& registerSharedPtrTable(std::type_index iTypeIndex);
763 
764 public:
765  //! 共有ポインタ(例えばstd::shared_ptr)回復用のテーブル
766  template<typename tTypeList>
767  tTypeList& getSharedPtrTable(std::type_index iTypeIndex)
768  {
769  SharedPtrTable& aSharedPtrTable=registerSharedPtrTable(iTypeIndex);
770 
771  // 実テーブルが未生成なら生成する
772  if (!aSharedPtrTable.mHolder)
773  {
774  aSharedPtrTable.mHolder.reset(new SharedPtrTable::Holder<tTypeList>);
775  }
776 
777  SharedPtrTable::Holder<tTypeList>* aHolder=
778  dynamic_cast<SharedPtrTable::Holder<tTypeList>*>(aSharedPtrTable.mHolder.get());
779  return aHolder->mList;
780  }
781 
782 // ***************************************************************************
783 // シリアライズ/デシリアライズ補助
784 // Theolizerの内部用
785 // ***************************************************************************
786 
787 private:
788  friend THEOLIZER_INTERNAL_DLL bool isLastVersion();
789  friend THEOLIZER_INTERNAL_DLL bool isSaver();
790  friend THEOLIZER_INTERNAL_DLL unsigned& getUpVersionCount();
791 
792  // 最新版処理
793  bool isLastVersion() const {return mGlobalVersionNo == mLastGlobalVersionNo;}
794 
795  // 保存処理
796  bool isSaver() const {return mIsSaver;}
797 
798  // upVersionカウンタ(upVersionによる設定を管理する)
799  // 0 :バージョン・ダウン処理中、または、save後のバージョン・アップ処理中
800  // 1-:load後のバージョン・アップ処理中
801  unsigned mUpVersionCount;
802 
803 // ***************************************************************************
804 // シリアライズ機能群
805 // ***************************************************************************
806 
807 protected:
808  CheckMode mCheckMode;
809  ElementsMapping mElementsMapping;
810  bool mIsShared;
811  int mIndent;
812  bool mCancelPrettyPrint;
813 
814 public:
815  //! 現在のCheckMode返却(@ref MemberFunctions 参照)
816  CheckMode getCheckMode() { return mCheckMode; }
817 
818 //----------------------------------------------------------------------------
819 // トップ・レベル処理補助クラス
820 //----------------------------------------------------------------------------
821 
822 protected:
823  struct THEOLIZER_INTERNAL_DLL AutoRestoreSaveProcess
824  {
825  BaseSerializer& mSerializer;
826  ElementsMapping mElementsMapping;
827  int mIndent;
828  bool mCancelPrettyPrint;
829 
830  AutoRestoreSaveProcess(BaseSerializer& iSerializer, size_t iTypeIndex);
831  ~AutoRestoreSaveProcess() noexcept(false);
832  };
833 
834 //----------------------------------------------------------------------------
835 // グループ処理補助クラス
836 //----------------------------------------------------------------------------
837 
838  struct THEOLIZER_INTERNAL_DLL AutoRestoreSave
839  {
840  BaseSerializer& mSerializer;
841  ElementsMapping mElementsMapping;
842  int mIndent;
843  bool mCancelPrettyPrint;
844  AutoRestoreSave
845  (
846  BaseSerializer& iSerializer,
847  ElementsMapping iElementsMapping=emOrder,
848  bool iCancelPrettyPrint=false
849  );
850  ~AutoRestoreSave() noexcept(false);
851  };
852 
853 //----------------------------------------------------------------------------
854 // 各種構造処理補助クラス
855 // クラス
856 // 配列
857 // ポインタ
858 // オーナ・ポインタ
859 // 被ポインタ
860 // 参照(動的ポリモーフィズム時のみ)
861 //----------------------------------------------------------------------------
862 
863  struct THEOLIZER_INTERNAL_DLL AutoRestoreSaveStructure
864  {
865  BaseSerializer& mSerializer;
866  ElementsMapping mElementsMapping;
867  Structure mStructure;
868  std::unique_ptr<std::string> mTypeName; // saveStructureStart()が変更するので注意
869  int mIndent;
870  bool mCancelPrettyPrint;
871 
872  AutoRestoreSaveStructure
873  (
874  BaseSerializer& iSerializer,
875  ElementsMapping iElementsMapping,
876  Structure iStructure,
877  std::size_t iTypeIndex=kInvalidSize,
878  std::size_t iObjectId=kInvalidSize,
879  bool iCancelPrettyPrint=false
880  );
881  ~AutoRestoreSaveStructure() noexcept(false);
882  };
883 
884 //----------------------------------------------------------------------------
885 // バージョン番号対応表
886 //----------------------------------------------------------------------------
887 
888  // 派生Serializerに対するバージョン番号
889 protected:
890  unsigned mSerializerVersionNo;
891 
892  // 各TypeIndexに対するバージョン番号
893 private:
894  VersionNoList mVersionNoList;
895 
896 //----------------------------------------------------------------------------
897 // 型情報保存
898 //----------------------------------------------------------------------------
899 
900 protected:
901 
902 // ---<<< 各TypeIndexに対するバージョン番号対応表作成 >>>---
903 
904  void createVersionNoTable();
905 
906 // ---<<< ヘッダ内型情報保存 >>>---
907 
908  // 通常シリアライズ
909  void writeHeaderTypeInfo();
910 
911 // ---<<< トップ・レベル保存前後処理 >>>---
912 
913  std::string getTypeName(std::size_t iTypeIndex);
914  void saveProcessStart(std::size_t iTypeIndex);
915  void saveProcessEnd();
916 
917 //----------------------------------------------------------------------------
918 // 中継用仮想関数群
919 //----------------------------------------------------------------------------
920 
921 protected:
922 
923 // ---<<< 制御用 >>>---
924 
925  virtual void writePreElement(bool iDoProcess=false) {THEOLIZER_INTERNAL_ABORT("");}
926  virtual void saveGroupStart(bool iIsTop=false) {THEOLIZER_INTERNAL_ABORT("");}
927  virtual void saveGroupEnd(bool iIsTop=false) {THEOLIZER_INTERNAL_ABORT("");}
928  virtual void saveStructureStart
929  (Structure iStructure, std::string& ioTypeName, std::size_t iObjectId)
930  {saveGroupStart();}
931  virtual void saveStructureEnd(Structure iStructure, std::string const& iTypeName)
932  {saveGroupEnd();}
933  virtual void saveObjectId(std::size_t iObjectId, std::size_t iTypeIndex)
934  {saveControl(iObjectId);}
935  virtual void saveControl(int iControl) {THEOLIZER_INTERNAL_ABORT("");}
936  virtual void saveControl(long iControl) {THEOLIZER_INTERNAL_ABORT("");}
937  virtual void saveControl(long long iControl) {THEOLIZER_INTERNAL_ABORT("");}
938  virtual void saveControl(unsigned iControl) {THEOLIZER_INTERNAL_ABORT("");}
939  virtual void saveControl(unsigned long iControl) {THEOLIZER_INTERNAL_ABORT("");}
940  virtual void saveControl(unsigned long long iControl) {THEOLIZER_INTERNAL_ABORT("");}
941  virtual void saveControl(std::string const& iControl) {THEOLIZER_INTERNAL_ABORT("");}
942  virtual void saveElementName(ElementsMapping iElementsMapping, char const* iElementName)
943  {THEOLIZER_INTERNAL_ABORT("");}
944 
945 // ---<<< プリミティブ用 >>>---
946 
947  #define THEOLIZER_INTERNAL_DEF_PRIMITIVE(dType, dSymbol) \
948  virtual void savePrimitive(dType const& iPrimitive) {THEOLIZER_INTERNAL_ABORT("");}
949 
950  #include "primitive.inc"
951 
952 //----------------------------------------------------------------------------
953 // Switcher::save()からの呼び出し
954 //----------------------------------------------------------------------------
955 
956 // ---<<< 生配列処理 >>>---
957 
958  template<typename tBaseSerializer, typename tArrayType, TrackingMode tTrackingMode>
959  void saveArray(tArrayType& iArray)
960  {
961  AutoRestoreSaveStructure aAutoRestoreSaveStructure(*this, emOrder, Structure::Array);
962  for (size_t i=0; i < std::extent<tArrayType>::value; ++i)
963  {
964  AutoRestoreSerializeInfo aAutoRestoreSerializeInfo(*this, nullptr, i);
965 
966  writePreElement();
967  Switcher
968  <
969  tBaseSerializer,
970  typename std::remove_extent<tArrayType>::type,
971  false,
972  tTrackingMode
973  >::save(*this, iArray[i]);
974  }
975  }
976 
977 //----------------------------------------------------------------------------
978 // TheolizerVersion<>からの呼び出し
979 //----------------------------------------------------------------------------
980 
981 // ---<<< ClassType保存 >>>---
982 
983 private:
984  template<class tVersionType> friend void saveClass(BaseSerializer&, tVersionType&);
985 
986  template<class tVersionType>
987  void saveClassImpl(tVersionType& iVersion)
988  {
989  ElementsMapping aElementsMapping = tVersionType::Theolizer::kElementsMapping;
990  // ヘッダが有るなら、フォーマット上は順序対応でOK
991  if (CheckMode::TypeCheck <= mCheckMode)
992  {
993  aElementsMapping=emOrder;
994  }
995 
996  // データ内に型名保存
997  std::size_t aTypeIndex = kInvalidSize;
998  if (mCheckMode == CheckMode::TypeCheckInData)
999  {
1000  aTypeIndex = getTypeIndex<typename tVersionType::TheolizerTarget>();
1001  }
1002 
1003  AutoRestoreSaveStructure aAutoRestoreSaveStructure
1004  (*this, aElementsMapping, Structure::Class, aTypeIndex);
1005  BaseSerializer::AutoBaseProcessing aAutoBaseProcessing(*this);
1006  for (size_t i=0; !tVersionType::getElementTheolizer(i).isSentinel() ; ++i)
1007  {
1008  if (!mDestinations.isMatch(tVersionType::getElementTheolizer(i).getDestinations()))
1009  continue;
1010 
1011  // 基底クラスの処理が終わったら、オーナー処理中をクリアする
1012  if (!tVersionType::getElementTheolizer(i).isBaseClass())
1013  {
1014  mBaseProcessing=false;
1015  }
1016 
1017  char const* aElementName=tVersionType::getElementTheolizer(i).getName();
1018  AutoRestoreSerializeInfo aAutoRestoreSerializeInfo(*this, aElementName);
1019  writePreElement();
1020  saveElementName(aElementsMapping, aElementName);
1021  tVersionType::getElementTheolizer(i).saveElement(*this, iVersion);
1022  }
1023  }
1024 
1025 // ***************************************************************************
1026 // デシリアライズ機能群
1027 // ***************************************************************************
1028 
1029 protected:
1030 
1031 //----------------------------------------------------------------------------
1032 // トップ・レベル処理補助クラス
1033 //----------------------------------------------------------------------------
1034 
1035  struct THEOLIZER_INTERNAL_DLL AutoRestoreLoadProcess
1036  {
1037  BaseSerializer& mSerializer;
1038 
1039  AutoRestoreLoadProcess(BaseSerializer& iSerializer, size_t iTypeIndex);
1040  ~AutoRestoreLoadProcess() noexcept(false);
1041  };
1042 
1043 //----------------------------------------------------------------------------
1044 // グループ処理補助クラス
1045 //----------------------------------------------------------------------------
1046 
1047  struct THEOLIZER_INTERNAL_DLL AutoRestoreLoad
1048  {
1049  BaseSerializer& mSerializer;
1050  ElementsMapping mElementsMapping;
1051 
1052  AutoRestoreLoad(BaseSerializer& iSerializer,
1053  ElementsMapping iElementsMapping=emOrder);
1054  ~AutoRestoreLoad() noexcept(false);
1055  };
1056 
1057 //----------------------------------------------------------------------------
1058 // 各種構造処理補助クラス
1059 // クラス
1060 // 配列
1061 // ポインタ
1062 // オーナ・ポインタ
1063 // 被ポインタ
1064 // 参照(動的ポリモーフィズム時のみ)
1065 //----------------------------------------------------------------------------
1066 
1067  struct THEOLIZER_INTERNAL_DLL AutoRestoreLoadStructure
1068  {
1069  BaseSerializer& mSerializer;
1070  ElementsMapping mElementsMapping;
1071  Structure mStructure;
1072  std::unique_ptr<std::string> mTypeName; // loadStructureStart()が変更するので注意
1073  int mIndent;
1074  bool mCancelPrettyPrint;
1075 
1076  AutoRestoreLoadStructure
1077  (
1078  BaseSerializer& iSerializer,
1079  ElementsMapping iElementsMapping,
1080  Structure iStructure,
1081  std::size_t iTypeIndex=kInvalidSize,
1082  std::size_t* oObjectId=nullptr
1083  );
1084  ~AutoRestoreLoadStructure() noexcept(false);
1085  };
1086 
1087 //----------------------------------------------------------------------------
1088 // ヘッダ回復と型チェック
1089 //----------------------------------------------------------------------------
1090 
1091 protected:
1092  // 型リスト(TypeIndex基準用)
1093  struct SerializedTypeListI;
1094  std::unique_ptr<SerializedTypeListI> mSerializedTypeListI;
1095 
1096  // 型リスト(TypeName(型名)基準用)
1097  struct SerializedTypeListN;
1098  std::unique_ptr<SerializedTypeListN> mSerializedTypeListN;
1099 
1100  // 型名と型/バージョン番号対応表
1101  struct TypeNameMap;
1102  std::unique_ptr<TypeNameMap> mTypeNameMap;
1103 
1104  // プログラム側TypeIndexから
1105  // 型リスト(mSerializedTypeListI, mSerializedTypeListN)へのインデック対応表
1106  std::vector<std::size_t> mTypeIndexTable;
1107 
1108 // ---<<< 型名と型/バージョン番号対応表生成 >>>---
1109 
1110  void createTypeNameMap(bool iIsClassOnly=false);
1111 
1112 // ---<<< ヘッダ内型情報回復 >>>---
1113 
1114  // 通常デシリアライズ
1115  void readHeaderTypeInfo();
1116 
1117 // ---<<< TypeIndex一致判定 >>>---
1118 
1119  bool isMatchTypeIndex(size_t iSerializedTypeIndex,
1120  size_t iProgramTypeIndex);
1121 
1122 // ---<<< トップ・レベル回復前後処理 >>>---
1123 
1124  void loadProcessStart(size_t iTypeIndex);
1125  void loadProcessEnd();
1126 
1127 //----------------------------------------------------------------------------
1128 // 中継用仮想関数群
1129 //----------------------------------------------------------------------------
1130 
1131 protected:
1132 
1133 // ---<<< 制御用 >>>---
1134 
1135  virtual ReadStat readPreElement(bool iDoProcess=false) {THEOLIZER_INTERNAL_ABORT("");}
1136  virtual void disposeElement() {THEOLIZER_INTERNAL_ABORT("");}
1137  virtual void loadGroupStart(bool iIsTop=false) {THEOLIZER_INTERNAL_ABORT("");}
1138  virtual void loadGroupEnd(bool iIsTop=false) {THEOLIZER_INTERNAL_ABORT("");}
1139  virtual void loadStructureStart
1140  (Structure iStructure, std::string& ioTypeName, std::size_t* oObjectId)
1141  {THEOLIZER_INTERNAL_ABORT("");}
1142  virtual void loadStructureEnd(Structure iStructure, std::string const& iTypeName)
1143  {THEOLIZER_INTERNAL_ABORT("");}
1144  virtual void loadObjectId(std::size_t& oObjectId, std::size_t iTypeIndex)
1145  {loadControl(oObjectId);}
1146  virtual void loadTypeName(std::string& oTypeName) {loadControl(oTypeName);}
1147  virtual void loadControl(int& oControl) {THEOLIZER_INTERNAL_ABORT("");}
1148  virtual void loadControl(long& oControl) {THEOLIZER_INTERNAL_ABORT("");}
1149  virtual void loadControl(long long& oControl) {THEOLIZER_INTERNAL_ABORT("");}
1150  virtual void loadControl(unsigned& oControl) {THEOLIZER_INTERNAL_ABORT("");}
1151  virtual void loadControl(unsigned long& oControl) {THEOLIZER_INTERNAL_ABORT("");}
1152  virtual void loadControl(unsigned long long& oControl) {THEOLIZER_INTERNAL_ABORT("");}
1153  virtual void loadControl(std::string& oControl) {THEOLIZER_INTERNAL_ABORT("");}
1154  virtual std::string loadElementName(ElementsMapping iElementsMapping)
1155  {THEOLIZER_INTERNAL_ABORT("");}
1156 
1157 // ---<<< プリミティブ用 >>>---
1158 
1159  #define THEOLIZER_INTERNAL_DEF_PRIMITIVE(dType, dSymbol) \
1160  virtual void loadPrimitive(dType& iPrimitive) {THEOLIZER_INTERNAL_ABORT("");}
1161 
1162  #include "primitive.inc"
1163 
1164 //----------------------------------------------------------------------------
1165 // Switcher::load()からの呼び出し
1166 //----------------------------------------------------------------------------
1167 
1168 // ---<<< 生配列処理 >>>---
1169 
1170  template<typename tBaseSerializer, typename tArrayType, TrackingMode tTrackingMode>
1171  void loadArray(tArrayType& oArray)
1172  {
1173  AutoRestoreLoadStructure aAutoRestoreLoadStructure(*this, emOrder, Structure::Array);
1174  for (size_t i=0; true; ++i)
1175  {
1176  ReadStat aReadStat=readPreElement();
1177  if (!aReadStat)
1178  break;
1179 
1180  AutoRestoreSerializeInfo aAutoRestoreSerializeInfo(*this, nullptr, i);
1181 
1182  if (i < std::extent<tArrayType>::value)
1183  {
1184  Switcher
1185  <
1186  tBaseSerializer,
1187  typename std::remove_extent<tArrayType>::type,
1188  false,
1189  tTrackingMode
1190  >::load(*this, oArray[i]);
1191  }
1192  else
1193  {
1194  if (aReadStat == DontCare)
1195  break;
1196 
1197  // 破棄
1198  disposeElement();
1199  }
1200  }
1201  }
1202 
1203 //----------------------------------------------------------------------------
1204 // TheolizerVersion<>からの呼び出し
1205 //----------------------------------------------------------------------------
1206 
1207 private:
1208  std::string getDataElementName(std::size_t iDataTypeIndex, std::size_t iDataIndex);
1209 
1210 // ---<<< ClassType回復 >>>---
1211 
1212  template<class tVersionType> friend void loadClass(BaseSerializer&, tVersionType&);
1213 
1214  template<class tVersionType>
1215  void loadClassImpl(tVersionType& iVersion)
1216  {
1217 #if 0
1218 auto& aClassTypeInfo=ClassTypeInfo<typename tVersionType::TheolizerClass>::getInstance();
1219 std::cout << "loadClassImpl(" << aClassTypeInfo.getCName() << ") --- start\n";
1220 #endif
1221 
1222  ElementsMapping aElementsMapping = tVersionType::Theolizer::kElementsMapping;
1223  // ヘッダが有るなら、フォーマット上は順序対応でOK
1224  if (CheckMode::TypeCheck <= mCheckMode)
1225  {
1226  aElementsMapping=emOrder;
1227  }
1228 
1229  // データ内に型名保存
1230  std::size_t aTypeIndex = kInvalidSize;
1231  if (mCheckMode == CheckMode::TypeCheckInData)
1232  {
1233  aTypeIndex = getTypeIndex<typename tVersionType::TheolizerTarget>();
1234  }
1235 
1236  AutoRestoreLoadStructure aAutoRestoreLoadStructure
1237  (*this, aElementsMapping, Structure::Class, aTypeIndex);
1238  BaseSerializer::AutoBaseProcessing aAutoBaseProcessing(*this);
1239  // 要素がないならNOP
1240  if (tVersionType::getElementTheolizer(0).isSentinel())
1241  return;
1242 
1243  std::size_t aDataTypeIndex=0;
1244  if ((tVersionType::Theolizer::kElementsMapping == emName)
1245  && (CheckMode::TypeCheck <= mCheckMode))
1246  {
1247  if (aTypeIndex == kInvalidSize)
1248  {
1249  aTypeIndex = getTypeIndex<typename tVersionType::TheolizerTarget>();
1250  }
1251  aDataTypeIndex=mTypeIndexTable[aTypeIndex];
1252  THEOLIZER_INTERNAL_ASSERT(aDataTypeIndex != kInvalidSize,
1253  "aTypeIndex=%d aDataTypeIndex=%d TypeName=%s", aTypeIndex, aDataTypeIndex,
1254  THEOLIZER_INTERNAL_TYPE_NAME(typename tVersionType::TheolizerTarget));
1255  }
1256  std::size_t aDataIndex=0; // シリアライデ・データ側クラスの要素Index
1257  size_t aIndex=0; // プログラム側クラスの要素Index
1258  while(true)
1259  {
1260  ReadStat aReadStat=readPreElement();
1261  if (!aReadStat)
1262  break;
1263 
1264  std::string aElementName;
1265  if ((tVersionType::Theolizer::kElementsMapping == emName)
1266  && (CheckMode::TypeCheck <= mCheckMode))
1267  {
1268  aElementName=getDataElementName(aDataTypeIndex, aDataIndex++);
1269  }
1270  else
1271  {
1272  aElementName=loadElementName(aElementsMapping);
1273  }
1274 
1275  AutoRestoreSerializeInfo aAutoRestoreSerializeInfo(*this, aElementName.c_str());
1276 
1277  // 回復先を確定する
1278  size_t i=aIndex;
1279  bool aDoLoad=false;
1280  do
1281  {
1282  // 順序対応
1283  if (aElementName.empty())
1284  {
1285  // 最後に到達したら破棄
1286  if (tVersionType::getElementTheolizer(i).isSentinel())
1287  {
1288  aIndex=i;
1289  break;
1290  }
1291 
1292  // 保存先が一致したら回復
1293  if (mDestinations.isMatch
1294  (
1295  tVersionType::getElementTheolizer(i).getDestinations()
1296  )
1297  )
1298  {
1299  aIndex=i;
1300  aDoLoad=true;
1301  break;
1302  }
1303  }
1304 
1305  // 名前対応、かつ、名前一致
1306  else if (aElementName == tVersionType::getElementTheolizer(i).getName())
1307  {
1308  aIndex=i;
1309  aDoLoad=true;
1310  break;
1311  }
1312 
1313  // 次処理
1314  ++i;
1315  if (tVersionType::getElementTheolizer(i).isSentinel())
1316  {
1317  // 名前対応なら先頭へ戻す
1318  if (!aElementName.empty())
1319  {
1320  i=0;
1321  }
1322  // 順序対応ならループ終了
1323  else
1324  {
1325  break;
1326  }
1327  }
1328  }
1329  while(aIndex != i);
1330 
1331  // 回復 or 破棄処理
1332  if (aDoLoad)
1333  {
1334  // 基底クラスの処理が終わったら、オーナー処理中をクリアする
1335  if (!tVersionType::getElementTheolizer(aIndex).isBaseClass())
1336  {
1337  mBaseProcessing=false;
1338  }
1339 
1340  // 回復
1341  tVersionType::getElementTheolizer(aIndex).loadElement(*this, iVersion);
1342 //std::cout << " " << tVersionType::getElementTheolizer(aIndex).getName() << "\n";
1343 
1344  // 次処理
1345  aIndex++;
1346  if (tVersionType::getElementTheolizer(aIndex).isSentinel())
1347  {
1348  // FastSerializer(変更不可)の時は直ぐに終了
1349  if (aReadStat == DontCare)
1350  break;
1351  // 名前対応なら先頭へ戻す
1352  if (!aElementName.empty())
1353  {
1354  aIndex=0;
1355  }
1356  }
1357  }
1358  else
1359  {
1360  // FastSerializer(変更不可)の時は破棄しない
1361  if (aReadStat == DontCare)
1362  break;
1363 
1364  // 破棄
1365  disposeElement();
1366  }
1367  }
1368 #if 0
1369 std::cout << "loadClassImpl(" << aClassTypeInfo.getCName() << ") --- end\n";
1370 #endif
1371  }
1372 
1373 //----------------------------------------------------------------------------
1374 // ClassTypeの破棄処理
1375 //----------------------------------------------------------------------------
1376 
1377 protected:
1378  void disposeClass(ElementsMapping iElementsMapping);
1379 
1380 // ***************************************************************************
1381 // オブジェクト追跡機能群
1382 // ***************************************************************************
1383 
1384 //----------------------------------------------------------------------------
1385 // シリアライズ用オブジェクト・リスト
1386 // オブジェクトID=0はnullptr用に予約
1387 //----------------------------------------------------------------------------
1388 
1389 private:
1390  size_t mObjectId;
1391  struct SerializeList;
1392  std::unique_ptr<SerializeList> mSerializeList;
1393  void initSerializeList();
1394 
1395 //----------------------------------------------------------------------------
1396 // シリアライズ用オブジェクト登録
1397 // 戻り値はSerializeInfo&
1398 //----------------------------------------------------------------------------
1399 
1400  SerializeInfo& registerObject
1401  (
1402  void* iAddress,
1403  std::type_info const& iTypeInfo,
1404  TrackingMode iTrackingMode,
1405  bool* oIsSaved
1406  );
1407 
1408 //----------------------------------------------------------------------------
1409 // デシリアライズ用オブジェクト・リスト
1410 // オブジェクトID=0はnullptr用に予約
1411 //----------------------------------------------------------------------------
1412 
1413  struct DeserializeList;
1414  std::unique_ptr<DeserializeList> mDeserializeList;
1415 
1416 //----------------------------------------------------------------------------
1417 // デシリアライズ用回復済チェック
1418 // 戻り値:指定ObjectIdのオブジェクトが回復済ならtrue返却
1419 //----------------------------------------------------------------------------
1420 
1421  bool isLoadedObject(size_t iObjectId, void*& oPointer);
1422 
1423 //----------------------------------------------------------------------------
1424 // デシリアライズ用アドレス登録/回復
1425 // ポインタのアドレス登録/回復なら、oPointerが有効
1426 // オブジェクトのアドレスを登録済ポインタへ回復する時、iObjectが有効
1427 // 戻り値:追跡指定異常時、false
1428 //----------------------------------------------------------------------------
1429 
1430  void recoverObject
1431  (
1432  size_t iObjectId,
1433  void*& oPointer,
1434  std::type_info const& iTypeInfo,
1435  TrackingMode iTrackingMode,
1436  bool* oIsLoaded=nullptr
1437  );
1438 
1439 // ***************************************************************************
1440 // ポリモーフィズム対応
1441 // ***************************************************************************
1442 
1443 //----------------------------------------------------------------------------
1444 // 型名/TypeIndexを読み込み、対応するプログラム側のTypeIndexを求める
1445 //----------------------------------------------------------------------------
1446 
1447  virtual TypeIndexList& getProgramTypeIndex();
1448 
1449 // ***************************************************************************
1450 // メタ処理
1451 // ***************************************************************************
1452 
1453 #ifdef THEOLIZER_INTERNAL_ENABLE_META_SERIALIZER
1454 
1455 //----------------------------------------------------------------------------
1456 // メタ・シリアライズ
1457 //----------------------------------------------------------------------------
1458 
1459 protected:
1460  std::ostream* mOStream;
1461  bool mIsMetaMode;
1462 
1463  // メタ・データのシリアライズ
1464  void writeMetaData();
1465 
1466 private:
1467  // メタ・シリアライズ保存判定
1468  void judgeWriteTypes
1469  (
1470  std::size_t iTypeIndex,
1471  BaseTypeInfo* iTypeInfo,
1472  TypeInfoListImpl const& iTypeInfoList,
1473  std::vector<SaveStat>& ioSaveStatList
1474  );
1475 
1476  // プリミティブ(派生Serializer)のメタ・シリアライズ処理
1477  void writeMetaPrimitive();
1478 
1479  // enum型のメタ・シリアライズ処理
1480  void writeMetaEnum
1481  (
1482  std::vector<VersionNoList> const& iVersionNoLists,
1483  TypeInfoListImpl const& iTypeInfoList,
1484  std::vector<SaveStat>& ioSaveStatList
1485  );
1486 
1487  // クラスのメタ・シリアライズ処理
1488  struct UniqueNameSet;
1489  void writeMetaClass
1490  (
1491  std::vector<VersionNoList> const& iVersionNoLists,
1492  TypeInfoListImpl const& iTypeInfoList,
1493  std::vector<SaveStat>& ioSaveStatList,
1494  UniqueNameSet& ioUniqueNameSet
1495  );
1496 
1497 //----------------------------------------------------------------------------
1498 // メタ・デシリアライズ
1499 //----------------------------------------------------------------------------
1500 
1501 protected:
1502  // メタ・データのデシリアライズ
1503  void readMetaData();
1504 
1505  static char const* getCppName(std::string const& iPrimitiveName, unsigned iSerializerVersionNo)
1506  {
1507  return "";
1508  }
1509 #endif // THEOLIZER_INTERNAL_ENABLE_META_SERIALIZER
1510 };
1511 #ifndef THEOLIZER_INTERNAL_DOXYGEN
1512 
1513 //############################################################################
1514 // internal化のための中継処理
1515 //############################################################################
1516 
1517 // ***************************************************************************
1518 // 指定Serializerへの中継
1519 // ***************************************************************************
1520 
1521 template<class tVersionType>
1522 void saveClass(BaseSerializer& iBaseSerializer, tVersionType& iVersion)
1523 {
1524  iBaseSerializer.saveClassImpl(iVersion);
1525 }
1526 
1527 template<class tVersionType>
1528 void loadClass(BaseSerializer& iBaseSerializer, tVersionType& iVersion)
1529 {
1530  iBaseSerializer.loadClassImpl(iVersion);
1531 }
1532 
1533 // ***************************************************************************
1534 // 現在処理中のSerializerの状態獲得
1535 // ***************************************************************************
1536 
1537 THEOLIZER_INTERNAL_DLL bool isLastVersion();
1538 THEOLIZER_INTERNAL_DLL bool isSaver();
1539 THEOLIZER_INTERNAL_DLL unsigned& getUpVersionCount();
1540 
1541 //############################################################################
1542 // std::shared_ptrサポート
1543 //############################################################################
1544 
1545 // ***************************************************************************
1546 // mIsShared管理
1547 // ***************************************************************************
1548 
1549 class AutoRestoreIsShared
1550 {
1551  BaseSerializer& mSerializer;
1552  bool mIsShared;
1553 
1554 public:
1555  explicit AutoRestoreIsShared(BaseSerializer& iSerializer, bool iIsShared) :
1556  mSerializer(iSerializer),
1557  mIsShared(iSerializer.mIsShared)
1558  {
1559  mSerializer.mIsShared=iIsShared;
1560  }
1561  ~AutoRestoreIsShared()
1562  {
1563  mSerializer.mIsShared=mIsShared;
1564  }
1565  AutoRestoreIsShared(AutoRestoreIsShared const&) = delete;
1566  AutoRestoreIsShared& operator=(AutoRestoreIsShared const&) = delete;
1567 };
1568 
1569 //############################################################################
1570 // End
1571 //############################################################################
1572 
1573 #endif // THEOLIZER_INTERNAL_DOXYGEN
1574 } // namespace internal
1575 } // namespace theolizer
1576 
1577 // ***************************************************************************
1578 // 警告抑止解除
1579 // ***************************************************************************
1580 
1581 #ifdef _MSC_VER
1582  #pragma warning(pop)
1583 #endif
1584 
1585 #endif // THEOLIZER_INTERNAL_CORE_SERIALIZER_H
tTypeList & getSharedPtrTable(std::type_index iTypeIndex)
共有ポインタ(例えばstd::shared_ptr)回復用のテーブル
CheckMode
型チェック・モード
theolizer名前空間
Definition: base.h:53
unsigned getGlobalVersionNo() const
処理中のグローバル・バージョン番号返却(3-1-2.メンバ関数 参照)
エラー管理用クラス(シリアライザが継承する)
Definition: report.h:835
virtual void setCharIsMultiByte(bool)
std::stringをマルチ・パイト文字コードとして処理することを指定する(NOP)
型名による型チェック
CheckMode getCheckMode()
現在のCheckMode返却(3-1-2.メンバ関数 参照)