Theolizer  Version.1.2.0
serializer for C++ / Do you want to update your classes easily ?
core_switcher.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_SWITCHER_H)
32 #define THEOLIZER_INTERNAL_CORE_SWITCHER_H
33 
34 #include <initializer_list>
35 
36 #include "core_serializer.h"
37 
38 //############################################################################
39 // Begin
40 //############################################################################
41 
42 // ***************************************************************************
43 // 警告抑止
44 // ***************************************************************************
45 
46 #ifdef _MSC_VER
47  #pragma warning(push)
48  #pragma warning(disable:4100 4127 4189)
49 #endif
50 
51 namespace theolizer
52 {
53 namespace internal
54 {
55 #ifndef THEOLIZER_INTERNAL_DOXYGEN
56 
57 //############################################################################
58 // 型管理
59 //############################################################################
60 
61 // ***************************************************************************
62 // Switcher(管理する型毎に特殊化する)
63 // シリアライズ/デシリアライズにおける型毎の分岐を実現する
64 // ***************************************************************************
65 
66 //----------------------------------------------------------------------------
67 // プライマリーSwitcher(エラー)
68 //----------------------------------------------------------------------------
69 
70 template<class tBaseSerializer, typename tType, bool tIsRegister,
71  TrackingMode tTrackingMode, class tEnable>
72 struct Switcher
73 {
74  // 保存
75  static void save(tBaseSerializer& iSerializer, tType& iInstance)
76  {
77  static_assert(Ignore<tType>::kFalse, "This is not serializable class.");
78 //std::cout << "save(" << THEOLIZER_INTERNAL_TYPE_NAME(tType) << ") illegal!!\n";
79  }
80  // 回復
81  static void load(tBaseSerializer& iSerializer, tType& iInstance)
82  {
83  static_assert(Ignore<tType>::kFalse, "This is not serializable class.");
84 //std::cout << "load(" << THEOLIZER_INTERNAL_TYPE_NAME(tType) << ") illegal!!\n";
85  }
86 };
87 
88 //----------------------------------------------------------------------------
89 // ポインタ型(オブジェクト追跡)用Switcher
90 //----------------------------------------------------------------------------
91 
92 #define THEOLIZER_INTERNAL_NON_FOUND_DERIVED(dBase) \
93  THEOLIZER_INTERNAL_DATA_ERROR( \
94  u8"Can not find the derived class for %1%." \
95  " Please specify the derived class by THEOLIZER_REGISTER_CLASS((derived class));",\
96  dBase.getCName())
97 
98 // ---<<< オブジェクト実体の保存 >>>---
99 
100 // ClassType以外
101 template<class tBaseSerializer, typename tType, class tEnalbe=void>
102 struct SavePointer
103 {
104  static void save(tBaseSerializer& iSerializer, tType*& iPointer)
105  {
106  Switcher<tBaseSerializer, tType, false, etmDefault>::save(iSerializer, *iPointer);
107  }
108 };
109 
110 // 侵入型
111 template<class tBaseSerializer, typename tClassType>
112 struct SavePointer<tBaseSerializer, tClassType, EnableIf<IsIntrusive<tClassType>::value> >
113 {
114  static void save(tBaseSerializer& iSerializer, tClassType*& iPointer)
115  {
116  tClassType* aPointer=iPointer;
117  auto& aClassTypeInfo=ClassTypeInfo<tClassType>::getInstance();
118  bool ret=aClassTypeInfo.saveTypeInstance
119  (
120  iSerializer,
121  iPointer,
122  std::type_index(typeid(*aPointer))
123  );
124  if (!ret)
125  {
126  THEOLIZER_INTERNAL_NON_FOUND_DERIVED(aClassTypeInfo);
127  }
128  }
129 };
130 
131 // 非侵入型
132 template<class tBaseSerializer, typename tClassType>
133 struct SavePointer
134 <
135  tBaseSerializer,
136  tClassType,
137  EnableIf<IsNonIntrusive<tClassType>::value>
138 >
139 {
140  static void save(tBaseSerializer& iSerializer, tClassType*& iPointer)
141  {
142  typedef TheolizerNonIntrusive<tClassType> NonIntrusiveType;
143  auto& aClassTypeInfo=ClassTypeInfo<NonIntrusiveType>::getInstance();
144  bool ret=aClassTypeInfo.saveTypeInstance
145  (
146  iSerializer,
147  reinterpret_cast<NonIntrusiveType*&>(iPointer),
148  std::type_index(typeid(*iPointer))
149  );
150  if (!ret)
151  {
152  THEOLIZER_INTERNAL_NON_FOUND_DERIVED(aClassTypeInfo);
153  }
154  }
155 };
156 
157 // ---<<< オブジェクト実体の回復 >>>---
158 
159 // ClassType以外
160 template<class tBaseSerializer, typename tType, class tEnalbe=void>
161 struct LoadPointer
162 {
163  static void load(tBaseSerializer& iSerializer, tType*& oPointer)
164  {
165  // 未回復の時、nullptrなら領域獲得
166  // (配列型へのポインタに対応するためreinterpret_castする)
167  if (!oPointer) oPointer = reinterpret_cast<tType*>(new tType());
168 
169  // オブジェクトを回復する
170  Switcher<tBaseSerializer, tType, false, etmDefault
171  >::load(iSerializer, *oPointer);
172  }
173 };
174 
175 // 侵入型
176 template<class tBaseSerializer, typename tClassType>
177 struct LoadPointer<tBaseSerializer, tClassType, EnableIf<IsIntrusive<tClassType>::value> >
178 {
179  static void load(tBaseSerializer& iSerializer, tClassType*& oPointer)
180  {
181  // オブジェクトを回復する
182  auto& aClassTypeInfo=ClassTypeInfo<tClassType>::getInstance();
183  bool ret;
184  // 通常のデータ交換
185  if (iSerializer.mCheckMode != CheckMode::InMemory)
186  {
187  ret=aClassTypeInfo.loadTypeInstance
188  (
189  iSerializer,
190  oPointer,
191  iSerializer.getProgramTypeIndex()
192  );
193  }
194  // メモリ内のデータ交換(TypeIndexが変化しない)
195  else
196  {
197  size_t aTypeIndex=0;
198  iSerializer.loadControl(aTypeIndex);
199  TypeIndexList aTypeIndexList;
200  aTypeIndexList.emplace_back(aTypeIndex);
201  ret=aClassTypeInfo.loadTypeInstance
202  (
203  iSerializer,
204  oPointer,
205  aTypeIndexList
206  );
207  }
208  if (!ret)
209  {
210  THEOLIZER_INTERNAL_NON_FOUND_DERIVED(aClassTypeInfo);
211  }
212  }
213 };
214 
215 // 非侵入型
216 template<class tBaseSerializer, typename tClassType>
217 struct LoadPointer<tBaseSerializer, tClassType, EnableIf<IsNonIntrusive<tClassType>::value> >
218 {
219  static void load(tBaseSerializer& iSerializer, tClassType*& oPointer)
220  {
221  // オブジェクトを回復する
222  typedef TheolizerNonIntrusive<tClassType> NonIntrusiveType;
223  auto& aClassTypeInfo=ClassTypeInfo<NonIntrusiveType>::getInstance();
224  bool ret;
225  // 通常のデータ交換
226  if (iSerializer.mCheckMode != CheckMode::InMemory)
227  {
228  ret=aClassTypeInfo.loadTypeInstance
229  (
230  iSerializer,
231  reinterpret_cast<NonIntrusiveType*&>(oPointer),
232  iSerializer.getProgramTypeIndex()
233  );
234  }
235  // メモリ内のデータ交換(TypeIndexが変化しない)
236  else
237  {
238  size_t aTypeIndex=0;
239  iSerializer.loadControl(aTypeIndex);
240  TypeIndexList aTypeIndexList;
241  aTypeIndexList.emplace_back(aTypeIndex);
242  ret=aClassTypeInfo.loadTypeInstance
243  (
244  iSerializer,
245  reinterpret_cast<NonIntrusiveType*&>(oPointer),
246  aTypeIndexList
247  );
248  }
249  if (!ret)
250  {
251  THEOLIZER_INTERNAL_NON_FOUND_DERIVED(aClassTypeInfo);
252  }
253  }
254 };
255 
256 //----------------------------------------------------------------------------
257 // ポインタ型用Switcher本体
258 //----------------------------------------------------------------------------
259 
260 // ---<<< オーナー・ポインタのdelete >>>---
261 
262 template
263 <
264  typename tPointerType,
265  TrackingMode tTrackingMode,
266  THEOLIZER_INTERNAL_OVERLOAD((tTrackingMode != etmOwner))
267 >
268 void deletePointer(tPointerType iPointer)
269 {
270 }
271 
272 template
273 <
274  typename tPointerType,
275  TrackingMode tTrackingMode,
276  THEOLIZER_INTERNAL_OVERLOAD
277  (
278  (tTrackingMode == etmOwner)
279  && (!std::is_array<typename std::remove_pointer<tPointerType>::type>::value)
280  )
281 >
282 void deletePointer(tPointerType iPointer)
283 {
284  delete iPointer;
285 }
286 
287 template
288 <
289  typename tPointerType,
290  TrackingMode tTrackingMode,
291  THEOLIZER_INTERNAL_OVERLOAD
292  (
293  (tTrackingMode == etmOwner)
294  && (std::is_array<typename std::remove_pointer<tPointerType>::type>::value)
295  )
296 >
297 void deletePointer(tPointerType iPointer)
298 {
299  delete[] iPointer;
300 }
301 
302 // ---<<< 本体 >>>---
303 
304 template<class tBaseSerializer,typename tPointerType,bool tIsRegister,TrackingMode tTrackingMode>
305 struct Switcher
306 <
307  tBaseSerializer,
308  tPointerType,
309  tIsRegister,
310  tTrackingMode,
311  EnableIf<std::is_pointer<tPointerType>::value>
312 >
313 {
314  // 保存
315  static void save(tBaseSerializer& iSerializer, tPointerType& iPointer)
316  {
317  // const外し
318  typedef typename RemoveCV<tPointerType>::type PointerType;
319  // pointer外し
320  typedef typename std::remove_pointer<PointerType>::type PointeeType;
321 
322  bool aIsSaved;
323 //std::cout << "Switcher(Pointer) " << THEOLIZER_INTERNAL_TYPE_NAME(tPointerType)
324 // << " " << THEOLIZER_INTERNAL_TYPE_NAME_VAR(iPointer)
325 // << " " << typeid(iPointer).name() << "\n";
326  SerializeInfo& aSerializeInfo=
327  iSerializer.registerObject
328  (
329  const_cast<PointerType&>(iPointer),
330  typeid(PointerType&),
331  tTrackingMode,
332  &aIsSaved
333  );
334 
335  // ポイント先の型のTypeIndex取り出し
336  std::size_t aTypeIndex = theolizer::internal::kInvalidSize;
337  if (iSerializer.mCheckMode == theolizer::CheckMode::TypeCheckInData)
338  {
339  aTypeIndex = theolizer::internal::getTypeIndex<PointeeType>();
340  }
341 
342  // 追跡指定がないなら、オブジェクトIDを保存するのみ
343  if (tTrackingMode == etmDefault)
344  {
345  iSerializer.saveObjectId(aSerializeInfo.mObjectId, aTypeIndex);
346  }
347 
348  // 追跡指定有り
349  else
350  {
351  // 開始/終了マーク処理
352  BaseSerializer::AutoRestoreSaveStructure aAutoRestoreSaveStructure
353  (
354  iSerializer,
355  emOrder,
356  (iSerializer.mRefProcessing)?Structure::Reference:Structure::OwnerPointer,
357  aTypeIndex,
358  aSerializeInfo.mObjectId,
359  true
360  );
361 
362  // クラス・インスタンスのオブジェクト追跡中
363  BaseSerializer::AutoClassTracking aAutoClassTracking(iSerializer);
364 
365  // 未保存の時のみ保存する
366  if (!aIsSaved)
367  {
368  iSerializer.writePreElement();
369  SavePointer<tBaseSerializer,
370  PointeeType
371  >::save(iSerializer, const_cast<PointerType&>(iPointer));
372  aSerializeInfo.mStatus=etsProcessed;
373  }
374  }
375  iSerializer.mRequireClearTracking=true;
376  }
377  // 回復
378  static void load(tBaseSerializer& iSerializer, tPointerType& oPointer)
379  {
380  // const外し
381  typedef typename RemoveCV<tPointerType>::type PointerType;
382  // pointer外し
383  typedef typename std::remove_pointer<PointerType>::type PointeeType;
384 
385  // ポイント先の型のTypeIndex取り出し
386  std::size_t aTypeIndex = theolizer::internal::kInvalidSize;
387  if (iSerializer.mCheckMode == theolizer::CheckMode::TypeCheckInData)
388  {
389  aTypeIndex = theolizer::internal::getTypeIndex<PointeeType>();
390  }
391 
392  // 追跡指定なし
393  if (tTrackingMode == etmDefault)
394  {
395  // オブジェクトID回復
396  size_t aObjectId;
397  iSerializer.loadObjectId(aObjectId, aTypeIndex);
398  iSerializer.recoverObject
399  (
400  aObjectId,
401  reinterpret_cast<void*&>(const_cast<PointerType&>(oPointer)),
402  typeid(PointerType&),
403  tTrackingMode
404  );
405  }
406 
407  // 追跡指定有り
408  else
409  {
410  size_t aObjectId;
411 
412  // 開始/終了マーク処理
413  BaseSerializer::AutoRestoreLoadStructure aAutoRestoreLoadStructure
414  (
415  iSerializer,
416  emOrder,
417  (iSerializer.mRefProcessing)?Structure::Reference:Structure::OwnerPointer,
418  aTypeIndex,
419  &aObjectId
420  );
421 
422  // クラス・インスタンスのオブジェクト追跡中
423  BaseSerializer::AutoClassTracking aAutoClassTracking(iSerializer);
424 
425  void* aPointer;
426  bool aIsLoaded=iSerializer.isLoadedObject(aObjectId, aPointer);
427  if (!aIsLoaded)
428  {
429  if (!iSerializer.readPreElement())
430  {
431  THEOLIZER_INTERNAL_DATA_ERROR(u8"Format Error.");
432  }
433  LoadPointer
434  <
435  tBaseSerializer,
436  typename std::remove_pointer<PointerType>::type
437  >::load(iSerializer, const_cast<PointerType&>(oPointer));
438  }
439  // オブジェクトのアドレス回復
440  tPointerType aPointerBak=oPointer;
441  iSerializer.recoverObject
442  (
443  aObjectId,
444  reinterpret_cast<void*&>(const_cast<PointerType&>(oPointer)),
445  typeid(oPointer),
446  tTrackingMode
447  );
448 
449  // オーナー・ポインタが書き換わっていたら解放する
450  if (aPointerBak != oPointer)
451  {
452  deletePointer<tPointerType, tTrackingMode>(aPointerBak);
453  }
454  }
455  iSerializer.mRequireClearTracking=true;
456  }
457 };
458 
459 //----------------------------------------------------------------------------
460 // トップレベル生配列用Switcher本体
461 //----------------------------------------------------------------------------
462 
463 template<class tBaseSerializer, typename tArrayType, bool tIsRegister, TrackingMode tTrackingMode>
464 struct Switcher
465 <
466  tBaseSerializer,
467  tArrayType,
468  tIsRegister,
469  tTrackingMode,
470  EnableIf<std::is_array<tArrayType>::value>
471 >
472 {
473  // 保存
474  static void save(tBaseSerializer& iSerializer, tArrayType& iArray)
475  {
476  iSerializer.template saveArray<tBaseSerializer, tArrayType, tTrackingMode>(iArray);
477  }
478  // 回復
479  static void load(tBaseSerializer& iSerializer, tArrayType& oArray)
480  {
481  iSerializer.template loadArray<tBaseSerializer, tArrayType, tTrackingMode>(oArray);
482  }
483 };
484 
485 //----------------------------------------------------------------------------
486 // 生配列用TheolizerVersion用Switcher本体
487 //----------------------------------------------------------------------------
488 
489 template<class tBaseSerializer, class tVersionType, bool tIsRegister, TrackingMode tTrackingMode>
490 struct Switcher
491 <
492  tBaseSerializer,
493  tVersionType,
494  tIsRegister,
495  tTrackingMode,
496  typename tVersionType::TheolizerArrayVersion
497 >
498 {
499  // 保存
500  static void save(tBaseSerializer& iSerializer, tVersionType& iArray)
501  {
502  iSerializer.template saveArray
503  <
504  tBaseSerializer,
505  typename tVersionType::VersionArray,
506  tTrackingMode
507  >(iArray.get());
508  }
509  // 回復
510  static void load(tBaseSerializer& iSerializer, tVersionType& oArray)
511  {
512  iSerializer.template loadArray
513  <
514  tBaseSerializer,
515  typename tVersionType::VersionArray,
516  tTrackingMode
517  >(oArray.get());
518  }
519 };
520 
521 //----------------------------------------------------------------------------
522 // 生配列用基本部用Switcher本体
523 //----------------------------------------------------------------------------
524 
525 template<class tBaseSerializer, class tVersionType, bool tIsRegister, TrackingMode tTrackingMode>
526 struct Switcher
527 <
528  tBaseSerializer,
529  tVersionType,
530  tIsRegister,
531  tTrackingMode,
532  typename tVersionType::TheolizerArrayUnderlying
533 >
534 {
535  // 保存
536  static void save(tBaseSerializer& iSerializer, tVersionType& iArray)
537  {
538  Switcher<tBaseSerializer,
539  typename tVersionType::UnderlyingType,
540  false,
541  tTrackingMode
542  >::save(iSerializer, iArray.get());
543  }
544  // 回復
545  static void load(tBaseSerializer& iSerializer, tVersionType& oArray)
546  {
547  Switcher<tBaseSerializer,
548  typename tVersionType::UnderlyingType,
549  false,
550  tTrackingMode
551  >::load(iSerializer, oArray.get());
552  }
553 };
554 
555 //----------------------------------------------------------------------------
556 // 侵入型用Switcher本体
557 //----------------------------------------------------------------------------
558 
559 template<class tBaseSerializer, class tTargetClass, bool tIsRegister, TrackingMode tTrackingMode>
560 struct Switcher
561 <
562  tBaseSerializer,
563  tTargetClass,
564  tIsRegister,
565  tTrackingMode,
566  EnableIf<IsIntrusive<tTargetClass>::value && !IsTheolizerVersion<tTargetClass>::value>
567 >
568 {
569  typedef tTargetClass IntrusiveType;
570 
571  // 保存
572  static void save(tBaseSerializer& iSerializer, tTargetClass& iInstance)
573  {
574  auto& aClassTypeInfo = ClassTypeInfo<IntrusiveType>::getInstance();
575 
576 #ifndef THEOLIZER_INTERNAL_DISABLE_NULL_REFERENCE
577  if (!&iInstance)
578  {
579  THEOLIZER_INTERNAL_WRONG_USING(
580  "This reference(%1%) is nullptr.",
581  aClassTypeInfo.getCName());
582  }
583 #endif
584 
585  // 参照のポリモーフィズム対応
586  // クラス内の基底クラスのシリアライズ中でない時に、
587  // 処理中の型と動的な型が不一致なら、ポリモーフィズム処理を適用する。
588  if ((!iSerializer.mBaseProcessing)
589  && (typeid(tTargetClass) != typeid(iInstance)))
590  {
591 //std::cout << "Derived!! " << typeid(tTargetClass).name()
592 // << ", " << typeid(iInstance).name() << "\n";
593  BaseSerializer::AutoRefProcessing aAutoRefProcessing(iSerializer);
594  tTargetClass* aInstancePtr = &iInstance;
595 
596  // オブジェクト追跡中でないなら、直接保存
597  if (tTrackingMode == etmDefault)
598  {
599  // 開始/終了マーク処理
600  BaseSerializer::AutoRestoreSave aAutoRestoreSave(iSerializer, emOrder, true);
601  iSerializer.writePreElement();
602  SavePointer<tBaseSerializer,
603  tTargetClass
604  >::save(iSerializer, aInstancePtr);
605  }
606  // オブジェクト追跡中なら、ポインタ保存(オブジェクト追跡する)
607  else
608  {
609  Switcher
610  <
611  tBaseSerializer,
612  typename std::add_pointer<tTargetClass>::type,
613  tIsRegister,
614  etmOwner
615  >::save(iSerializer, aInstancePtr);
616  }
617  return;
618  }
619 
620  // 通常処理
621  unsigned aVersionNo=iSerializer.mVersionNoList.at(aClassTypeInfo.mTypeIndex);
622  IntrusiveType* aInstancePtr = &iInstance;
623 
624  // 追跡モード修正(クラスのオブジェクト追跡中、かつ、基底クラス処理中なら追跡する)
625  TrackingMode aTrackingMode=tTrackingMode;
626  if ((aTrackingMode == etmDefault)
627  && (iSerializer.mClassTracking && iSerializer.mBaseProcessing))
628  {
629  aTrackingMode=etmPointee;
630  }
631  if (aTrackingMode == etmDefault)
632  {
633  IntrusiveType::Theolizer::saveClass(iSerializer, aInstancePtr, aVersionNo);
634  }
635  else
636  {
637  bool aIsSaved;
638 //std::cout << "Switcher(Intrusive) " << THEOLIZER_INTERNAL_TYPE_NAME(IntrusiveType) << "\n";
639  SerializeInfo& aSerializeInfo=
640  iSerializer.registerObject
641  (
642  &iInstance,
643  typeid(&iInstance),
644  aTrackingMode,
645  &aIsSaved
646  );
647 
648  // 型のTypeIndex取り出し
649  std::size_t aTypeIndex = theolizer::internal::kInvalidSize;
650  if (iSerializer.mCheckMode == theolizer::CheckMode::TypeCheckInData)
651  {
652  aTypeIndex = theolizer::internal::getTypeIndex<tTargetClass>();
653  }
654 
655  // 開始/終了マーク処理
656  BaseSerializer::AutoRestoreSaveStructure aAutoRestoreSaveStructure
657  (
658  iSerializer,
659  emOrder,
660  Structure::Pointee,
661  aTypeIndex,
662  aSerializeInfo.mObjectId,
663  true
664  );
665 
666  // クラス・インスタンスのオブジェクト追跡中
667  BaseSerializer::AutoClassTracking aAutoClassTracking(iSerializer);
668 
669  // 未保存の時のみ保存する
670  if (!aIsSaved)
671  {
672  iSerializer.writePreElement();
673  IntrusiveType::Theolizer::saveClass(iSerializer, aInstancePtr, aVersionNo);
674  }
675  }
676  }
677  // 回復
678  static void load(tBaseSerializer& iSerializer, tTargetClass& oInstance)
679  {
680  auto& aClassTypeInfo = ClassTypeInfo<IntrusiveType>::getInstance();
681 
682 #ifndef THEOLIZER_INTERNAL_DISABLE_NULL_REFERENCE
683  if (!&oInstance)
684  {
685  THEOLIZER_INTERNAL_WRONG_USING(
686  "This reference(%1%) is nullptr.",
687  aClassTypeInfo.getCName());
688  }
689 #endif
690 
691  // 参照のポリモーフィズム対応
692  // クラス内の基底クラスのシリアライズ中でない時に、
693  // 処理中の型と動的な型が不一致なら、ポリモーフィズム処理を適用する。
694  if ((!iSerializer.mBaseProcessing)
695  && (typeid(tTargetClass) != typeid(oInstance)))
696  {
697 //std::cout << "Derived!! " << typeid(tTargetClass).name()
698 // << ", " << typeid(oInstance).name() << "\n";
699  BaseSerializer::AutoRefProcessing aAutoRefProcessing(iSerializer);
700  tTargetClass* aInstancePtr = &oInstance;
701 
702  // オブジェクト追跡中でないなら、直接保存
703  if (tTrackingMode == etmDefault)
704  {
705  // 開始/終了マーク処理
706  BaseSerializer::AutoRestoreLoad aAutoRestoreLoad(iSerializer);
707  if (!iSerializer.readPreElement())
708  {
709  THEOLIZER_INTERNAL_DATA_ERROR(u8"Format Error.");
710  }
711  LoadPointer<tBaseSerializer,
712  tTargetClass
713  >::load(iSerializer, aInstancePtr);
714  }
715  // オブジェクト追跡中なら、ポインタ保存(オブジェクト追跡する)
716  else
717  {
718  Switcher
719  <
720  tBaseSerializer,
721  typename std::add_pointer<tTargetClass>::type,
722  tIsRegister,
723  etmOwner
724  >::load(iSerializer, aInstancePtr);
725  }
726  return;
727  }
728 
729  // 通常処理
730  unsigned aVersionNo=iSerializer.mVersionNoList.at(aClassTypeInfo.mTypeIndex);
731  IntrusiveType* aInstancePtr = &oInstance;
732 
733  // 追跡モード修正(クラスのオブジェクト追跡中、かつ、基底クラス処理中なら追跡する)
734  TrackingMode aTrackingMode=tTrackingMode;
735  if ((aTrackingMode == etmDefault)
736  && (iSerializer.mClassTracking && iSerializer.mBaseProcessing))
737  {
738  aTrackingMode=etmPointee;
739  }
740  if (aTrackingMode == etmDefault)
741  {
742  IntrusiveType::Theolizer::loadClass(iSerializer, aInstancePtr, aVersionNo);
743  }
744  else
745  {
746  // 型のTypeIndex取り出し
747  std::size_t aTypeIndex = theolizer::internal::kInvalidSize;
748  if (iSerializer.mCheckMode == theolizer::CheckMode::TypeCheckInData)
749  {
750  aTypeIndex = theolizer::internal::getTypeIndex<tTargetClass>();
751  }
752 
753  // 開始/終了マーク処理
754  size_t aObjectId=kInvalidSize;
755  BaseSerializer::AutoRestoreLoadStructure aAutoRestoreLoadStructure
756  (
757  iSerializer,
758  emOrder,
759  Structure::Pointee,
760  aTypeIndex,
761  &aObjectId
762  );
763 
764  // クラス・インスタンスのオブジェクト追跡中
765  BaseSerializer::AutoClassTracking aAutoClassTracking(iSerializer);
766 
767  bool aIsLoaded;
768  IntrusiveType* aPointer=&oInstance;
769 
770  // オブジェクトのアドレス回復
771  iSerializer.recoverObject
772  (
773  aObjectId,
774  reinterpret_cast<void*&>(aPointer),
775  typeid(aPointer),
776  aTrackingMode,
777  &aIsLoaded
778  );
779  // 未回復の時のみ回復する
780  if (!aIsLoaded)
781  {
782  if (!iSerializer.readPreElement())
783  {
784  THEOLIZER_INTERNAL_DATA_ERROR(u8"Format Error.");
785  }
786  IntrusiveType::Theolizer::loadClass(iSerializer, aInstancePtr, aVersionNo);
787  }
788  }
789  }
790 };
791 
792 //----------------------------------------------------------------------------
793 // 非侵入型用Switcher本体
794 // 対象クラスがconstの場合、TheolizerNonIntrusive<>が別物になるので、
795 // constを外したTheolizerNonIntrusive<>の有無をチェックする
796 //----------------------------------------------------------------------------
797 
798 template<class tBaseSerializer, class tTargetClass, bool tIsRegister, TrackingMode tTrackingMode>
799 struct Switcher
800 <
801  tBaseSerializer,
802  tTargetClass,
803  tIsRegister,
804  tTrackingMode,
805  EnableIf<IsNonIntrusive<tTargetClass>::value && !IsTheolizerVersion<tTargetClass>::value>
806 >
807 {
808  typedef TheolizerNonIntrusive<tTargetClass> NonIntrusiveType;
809  typedef typename NonIntrusiveType::TheolizerTarget TheolizerTarget;
810 
811  // 保存
812  static void save(tBaseSerializer& iSerializer, tTargetClass& iInstance)
813  {
814  auto& aClassTypeInfo = ClassTypeInfo<NonIntrusiveType>::getInstance();
815 
816 #ifndef THEOLIZER_INTERNAL_DISABLE_NULL_REFERENCE
817  if (!&iInstance)
818  {
819  THEOLIZER_INTERNAL_WRONG_USING(
820  "This reference(%1%) is nullptr.",
821  aClassTypeInfo.getCName());
822  }
823 #endif
824 
825  // 参照のポリモーフィズム対応
826  // クラス内の基底クラスのシリアライズ中でない時に、
827  // 処理中の型と動的な型が不一致なら、ポリモーフィズム処理を適用する。
828  if ((!iSerializer.mBaseProcessing)
829  && (typeid(tTargetClass) != typeid(iInstance)))
830  {
831 //std::cout << "Derived!! " << typeid(tTargetClass).name()
832 // << ", " << typeid(iInstance).name() << "\n";
833  BaseSerializer::AutoRefProcessing aAutoRefProcessing(iSerializer);
834  tTargetClass* aInstancePtr = &iInstance;
835 
836  // オブジェクト追跡中でないなら、直接保存
837  if (tTrackingMode == etmDefault)
838  {
839  // 開始/終了マーク処理
840  BaseSerializer::AutoRestoreSave aAutoRestoreSave(iSerializer, emOrder, true);
841  iSerializer.writePreElement();
842  SavePointer<tBaseSerializer,
843  tTargetClass
844  >::save(iSerializer, aInstancePtr);
845  }
846  // オブジェクト追跡中なら、ポインタ保存(オブジェクト追跡する)
847  else
848  {
849  Switcher
850  <
851  tBaseSerializer,
852  typename std::add_pointer<tTargetClass>::type,
853  tIsRegister,
854  etmOwner
855  >::save(iSerializer, aInstancePtr);
856  }
857  return;
858  }
859 
860  // 通常処理
861  unsigned aVersionNo=iSerializer.mVersionNoList.at(aClassTypeInfo.mTypeIndex);
862  NonIntrusiveType* aInstancePtr = static_cast<NonIntrusiveType*>(&iInstance);
863 
864  // 追跡モード修正(クラスのオブジェクト追跡中、かつ、基底クラス処理中なら追跡する)
865  TrackingMode aTrackingMode=tTrackingMode;
866  if ((aTrackingMode == etmDefault)
867  && (iSerializer.mClassTracking && iSerializer.mBaseProcessing))
868  {
869  aTrackingMode=etmPointee;
870  }
871  if (aTrackingMode == etmDefault)
872  {
873  NonIntrusiveType::Theolizer::saveClass(iSerializer, aInstancePtr, aVersionNo);
874  }
875  else
876  {
877  bool aIsSaved;
878 //std::cout << "Switcher(NonIntrusive) "<<THEOLIZER_INTERNAL_TYPE_NAME(NonIntrusiveType) << "\n";
879  SerializeInfo& aSerializeInfo=
880  iSerializer.registerObject
881  (
882  aInstancePtr,
883  typeid(typename std::add_pointer<TheolizerTarget>::type),
884  aTrackingMode,
885  &aIsSaved
886  );
887 
888  // 型のTypeIndex取り出し
889  std::size_t aTypeIndex = theolizer::internal::kInvalidSize;
890  if (iSerializer.mCheckMode == theolizer::CheckMode::TypeCheckInData)
891  {
892  aTypeIndex = theolizer::internal::getTypeIndex<tTargetClass>();
893  }
894 
895  // 開始/終了マーク処理
896  BaseSerializer::AutoRestoreSaveStructure aAutoRestoreSaveStructure
897  (
898  iSerializer,
899  emOrder,
900  Structure::Pointee,
901  aTypeIndex,
902  aSerializeInfo.mObjectId,
903  true
904  );
905 
906  // クラス・インスタンスのオブジェクト追跡中
907  BaseSerializer::AutoClassTracking aAutoClassTracking(iSerializer);
908 
909  // 未保存の時のみ保存する
910  if (!aIsSaved)
911  {
912  iSerializer.writePreElement();
913  NonIntrusiveType::Theolizer::saveClass(iSerializer, aInstancePtr, aVersionNo);
914  }
915  }
916  }
917  // 回復
918  static void load(tBaseSerializer& iSerializer, tTargetClass& oInstance)
919  {
920  auto& aClassTypeInfo = ClassTypeInfo<NonIntrusiveType>::getInstance();
921 
922 #ifndef THEOLIZER_INTERNAL_DISABLE_NULL_REFERENCE
923  if (!&oInstance)
924  {
925  THEOLIZER_INTERNAL_WRONG_USING(
926  "This reference(%1%) is nullptr.",
927  aClassTypeInfo.getCName());
928  }
929 #endif
930 
931  // 参照のポリモーフィズム対応
932  // クラス内の基底クラスのシリアライズ中でない時に、
933  // 処理中の型と動的な型が不一致なら、ポリモーフィズム処理を適用する。
934  if ((!iSerializer.mBaseProcessing)
935  && (typeid(tTargetClass) != typeid(oInstance)))
936  {
937 //std::cout << "Derived!! " << typeid(tTargetClass).name()
938 // << ", " << typeid(oInstance).name() << "\n";
939  BaseSerializer::AutoRefProcessing aAutoRefProcessing(iSerializer);
940  tTargetClass* aInstancePtr = &oInstance;
941 
942  // オブジェクト追跡中でないなら、直接保存
943  if (tTrackingMode == etmDefault)
944  {
945  // 開始/終了マーク処理
946  BaseSerializer::AutoRestoreLoad aAutoRestoreLoad(iSerializer);
947  if (!iSerializer.readPreElement())
948  {
949  THEOLIZER_INTERNAL_DATA_ERROR(u8"Format Error.");
950  }
951  LoadPointer<tBaseSerializer,
952  tTargetClass
953  >::load(iSerializer, aInstancePtr);
954  }
955  // オブジェクト追跡中なら、ポインタ保存(オブジェクト追跡する)
956  else
957  {
958  Switcher
959  <
960  tBaseSerializer,
961  typename std::add_pointer<tTargetClass>::type,
962  tIsRegister,
963  etmOwner
964  >::load(iSerializer, aInstancePtr);
965  }
966  return;
967  }
968 
969  // 通常処理
970  unsigned aVersionNo=iSerializer.mVersionNoList.at(aClassTypeInfo.mTypeIndex);
971  NonIntrusiveType* aInstancePtr = static_cast<NonIntrusiveType*>(&oInstance);
972 
973  // 追跡モード修正(クラスのオブジェクト追跡中、かつ、基底クラス処理中なら追跡する)
974  TrackingMode aTrackingMode=tTrackingMode;
975  if ((aTrackingMode == etmDefault)
976  && (iSerializer.mClassTracking && iSerializer.mBaseProcessing))
977  {
978  aTrackingMode=etmPointee;
979  }
980  if (aTrackingMode == etmDefault)
981  {
982  NonIntrusiveType::Theolizer::loadClass(iSerializer, aInstancePtr, aVersionNo);
983  }
984  else
985  {
986  // 型のTypeIndex取り出し
987  std::size_t aTypeIndex = theolizer::internal::kInvalidSize;
988  if (iSerializer.mCheckMode == theolizer::CheckMode::TypeCheckInData)
989  {
990  aTypeIndex = theolizer::internal::getTypeIndex<tTargetClass>();
991  }
992 
993  // 開始/終了マーク処理
994  size_t aObjectId=kInvalidSize;
995  BaseSerializer::AutoRestoreLoadStructure aAutoRestoreLoadStructure
996  (
997  iSerializer,
998  emOrder,
999  Structure::Pointee,
1000  aTypeIndex,
1001  &aObjectId
1002  );
1003 
1004  // クラス・インスタンスのオブジェクト追跡中
1005  BaseSerializer::AutoClassTracking aAutoClassTracking(iSerializer);
1006 
1007  bool aIsLoaded;
1008  iSerializer.recoverObject
1009  (
1010  aObjectId,
1011  reinterpret_cast<void*&>(aInstancePtr),
1012  typeid(aInstancePtr),
1013  aTrackingMode,
1014  &aIsLoaded
1015  );
1016  // 未回復の時のみ回復する
1017  if (!aIsLoaded)
1018  {
1019  iSerializer.readPreElement();
1020  NonIntrusiveType::Theolizer::loadClass(iSerializer, aInstancePtr, aVersionNo);
1021  }
1022  }
1023  }
1024 };
1025 
1026 //----------------------------------------------------------------------------
1027 // 侵入型と非侵入型のTheolizerVersion用Switcher本体
1028 //----------------------------------------------------------------------------
1029 
1030 template<class tBaseSerializer, class tVersionType, bool tIsRegister, TrackingMode tTrackingMode>
1031 struct Switcher
1032 <
1033  tBaseSerializer,
1034  tVersionType,
1035  tIsRegister,
1036  tTrackingMode,
1037  EnableIf
1038  <
1039  IsTheolizerVersion<tVersionType>::value
1040  && !tVersionType::Theolizer::kIsEnum
1041  && !tVersionType::Theolizer::kIsArray
1042  >
1043 >
1044 {
1045  typedef typename tVersionType::TheolizerClass TheolizerClass;
1046  typedef typename tVersionType::TheolizerTarget TheolizerTarget;
1047 
1048  // 保存
1049  static void save(tBaseSerializer& iSerializer, tVersionType& iInstance)
1050  {
1051  // 追跡モード修正(クラスのオブジェクト追跡中、かつ、基底クラス処理中なら追跡する)
1052  TrackingMode aTrackingMode=tTrackingMode;
1053  if ((aTrackingMode == etmDefault)
1054  && (iSerializer.mClassTracking && iSerializer.mBaseProcessing))
1055  {
1056  aTrackingMode=etmPointee;
1057  }
1058  if (aTrackingMode == etmDefault)
1059  {
1060  iInstance.saveClass(iSerializer, tVersionType::Theolizer::kVersionNo);
1061  }
1062  else
1063  {
1064  bool aIsSaved;
1065 //std::cout << "Switcher(TheolizerVersion) "<<THEOLIZER_INTERNAL_TYPE_NAME(tVersionType) << "\n";
1066  SerializeInfo& aSerializeInfo=
1067  iSerializer.registerObject
1068  (
1069  iInstance.mTheolizerSpecials.mTarget,
1070  typeid(typename std::add_pointer<TheolizerTarget>::type),
1071  aTrackingMode,
1072  &aIsSaved
1073  );
1074 
1075  // 型のTypeIndex取り出し
1076  std::size_t aTypeIndex = theolizer::internal::kInvalidSize;
1077  if (iSerializer.mCheckMode == theolizer::CheckMode::TypeCheckInData)
1078  {
1079  aTypeIndex = theolizer::internal::getTypeIndex<TheolizerTarget>();
1080  }
1081 
1082  // 開始/終了マーク処理
1083  BaseSerializer::AutoRestoreSaveStructure aAutoRestoreSaveStructure
1084  (
1085  iSerializer,
1086  emOrder,
1087  Structure::Pointee,
1088  aTypeIndex,
1089  aSerializeInfo.mObjectId,
1090  true
1091  );
1092 
1093  // クラス・インスタンスのオブジェクト追跡中
1094  BaseSerializer::AutoClassTracking aAutoClassTracking(iSerializer);
1095 
1096  // 未保存の時のみ保存する
1097  if (!aIsSaved)
1098  {
1099  iSerializer.writePreElement();
1100  iInstance.saveClass(iSerializer, tVersionType::Theolizer::kVersionNo);
1101  }
1102  }
1103  }
1104  // 回復
1105  static void load(tBaseSerializer& iSerializer, tVersionType& oInstance)
1106  {
1107  // 追跡モード修正(クラスのオブジェクト追跡中、かつ、基底クラス処理中なら追跡する)
1108  TrackingMode aTrackingMode=tTrackingMode;
1109  if ((aTrackingMode == etmDefault)
1110  && (iSerializer.mClassTracking && iSerializer.mBaseProcessing))
1111  {
1112  aTrackingMode=etmPointee;
1113  }
1114  if (aTrackingMode == etmDefault)
1115  {
1116  oInstance.loadClass(iSerializer, tVersionType::Theolizer::kVersionNo);
1117  }
1118  else
1119  {
1120  // 型のTypeIndex取り出し
1121  std::size_t aTypeIndex = theolizer::internal::kInvalidSize;
1122  if (iSerializer.mCheckMode == theolizer::CheckMode::TypeCheckInData)
1123  {
1124  aTypeIndex = theolizer::internal::getTypeIndex<TheolizerTarget>();
1125  }
1126 
1127  // 開始/終了マーク処理
1128  size_t aObjectId=kInvalidSize;
1129  BaseSerializer::AutoRestoreLoadStructure aAutoRestoreLoadStructure
1130  (
1131  iSerializer,
1132  emOrder,
1133  Structure::Pointee,
1134  aTypeIndex,
1135  &aObjectId
1136  );
1137 
1138  // クラス・インスタンスのオブジェクト追跡中
1139  BaseSerializer::AutoClassTracking aAutoClassTracking(iSerializer);
1140 
1141  bool aIsLoaded;
1142  iSerializer.recoverObject
1143  (
1144  aObjectId,
1145  reinterpret_cast<void*&>(oInstance.mTheolizerSpecials.mTarget),
1146  typeid(oInstance.mTheolizerSpecials.mTarget),
1147  aTrackingMode,
1148  &aIsLoaded
1149  );
1150  // 未回復の時のみ回復する
1151  if (!aIsLoaded)
1152  {
1153  if (!iSerializer.readPreElement()) {
1154  THEOLIZER_INTERNAL_DATA_ERROR(u8"Format Error.");
1155  }
1156  oInstance.loadClass(iSerializer, tVersionType::Theolizer::kVersionNo);
1157  }
1158  }
1159  }
1160 };
1161 
1162 //----------------------------------------------------------------------------
1163 // 手動型基底クラス用Switcher
1164 //----------------------------------------------------------------------------
1165 
1166 template<class tBaseSerializer, class tBaseType, bool tIsRegister, TrackingMode tTrackingMode>
1167 struct Switcher
1168 <
1169  tBaseSerializer,
1170  tBaseType,
1171  tIsRegister,
1172  tTrackingMode,
1173  EnableIf<IsTheolizerBase<tBaseType>::value>
1174 >
1175 {
1176  typedef typename tBaseType::Target Target;
1177 
1178  // 保存
1179  static void save(tBaseSerializer& iSerializer, tBaseType& iInstance)
1180  {
1181  Switcher<tBaseSerializer,
1182  Target,
1183  tTrackingMode
1184  >::save(iSerializer, static_cast<Target&>(iInstance));
1185  }
1186  // 回復
1187  static void load(tBaseSerializer& iSerializer, tBaseType& oInstance)
1188  {
1189  Switcher<tBaseSerializer,
1190  Target,
1191  tTrackingMode
1192  >::load(iSerializer, static_cast<Target&>(oInstance));
1193  }
1194 };
1195 
1196 //----------------------------------------------------------------------------
1197 // EnumType用Switcher
1198 //----------------------------------------------------------------------------
1199 
1200 // ---<<< EnumType用Switcher本体 >>>---
1201 
1202 template<class tBaseSerializer, typename tEnumType, bool tIsRegister, TrackingMode tTrackingMode>
1203 struct Switcher
1204 <
1205  tBaseSerializer,
1206  tEnumType,
1207  tIsRegister,
1208  tTrackingMode,
1209  EnableIf<std::is_enum<tEnumType>::value>
1210 >
1211 {
1212  // 保存
1213  static void save(tBaseSerializer& iSerializer, tEnumType& iInstance)
1214  {
1215  unsigned aVersionNo=iSerializer.mVersionNoList.at(
1216  EnumTypeInfo<tEnumType>::getInstance().mTypeIndex);
1217 
1218  if (tTrackingMode == etmDefault)
1219  {
1220  TheolizerNonIntrusive<tEnumType>::Theolizer::
1221  saveEnum(iSerializer, iInstance, aVersionNo);
1222  }
1223  else
1224  {
1225  bool aIsSaved;
1226 //std::cout << "Switcher(Enum) " << THEOLIZER_INTERNAL_TYPE_NAME(tEnumType) << "\n";
1227  SerializeInfo& aSerializeInfo=
1228  iSerializer.registerObject
1229  (
1230  &iInstance,
1231  typeid(&iInstance),
1232  tTrackingMode,
1233  &aIsSaved
1234  );
1235 
1236  // 型のTypeIndex取り出し
1237  std::size_t aTypeIndex = theolizer::internal::kInvalidSize;
1238  if (iSerializer.mCheckMode == theolizer::CheckMode::TypeCheckInData)
1239  {
1240  aTypeIndex = theolizer::internal::getTypeIndex<tEnumType>();
1241  }
1242 
1243  // 開始/終了マーク処理
1244  BaseSerializer::AutoRestoreSaveStructure aAutoRestoreSaveStructure
1245  (
1246  iSerializer,
1247  emOrder,
1248  Structure::Pointee,
1249  aTypeIndex,
1250  aSerializeInfo.mObjectId,
1251  true
1252  );
1253 
1254  // 未保存の時のみ保存する
1255  if (!aIsSaved)
1256  {
1257  iSerializer.writePreElement();
1258  TheolizerNonIntrusive<tEnumType>::Theolizer::
1259  saveEnum(iSerializer, iInstance, aVersionNo);
1260  }
1261  }
1262  }
1263  // 回復
1264  static void load(tBaseSerializer& iSerializer, tEnumType& oInstance)
1265  {
1266  unsigned aVersionNo=iSerializer.mVersionNoList.at(
1267  EnumTypeInfo<tEnumType>::getInstance().mTypeIndex);
1268 
1269  if (tTrackingMode == etmDefault)
1270  {
1271  TheolizerNonIntrusive<tEnumType>::Theolizer::
1272  loadEnum(iSerializer,oInstance,aVersionNo);
1273  }
1274  else
1275  {
1276  // 型のTypeIndex取り出し
1277  std::size_t aTypeIndex = theolizer::internal::kInvalidSize;
1278  if (iSerializer.mCheckMode == theolizer::CheckMode::TypeCheckInData)
1279  {
1280  aTypeIndex = theolizer::internal::getTypeIndex<tEnumType>();
1281  }
1282 
1283  // 開始/終了マーク処理
1284  size_t aObjectId=kInvalidSize;
1285  BaseSerializer::AutoRestoreLoadStructure aAutoRestoreLoadStructure
1286  (
1287  iSerializer,
1288  emOrder,
1289  Structure::Pointee,
1290  aTypeIndex,
1291  &aObjectId
1292  );
1293 
1294  bool aIsLoaded;
1295  tEnumType* aPointer=&oInstance;
1296  iSerializer.recoverObject
1297  (
1298  aObjectId,
1299  reinterpret_cast<void*&>(aPointer),
1300  typeid(aPointer),
1301  tTrackingMode,
1302  &aIsLoaded
1303  );
1304  // 未回復の時のみ回復する
1305  if (!aIsLoaded)
1306  {
1307  iSerializer.readPreElement();
1308  TheolizerNonIntrusive<tEnumType>::Theolizer::
1309  loadEnum(iSerializer, oInstance, aVersionNo);
1310  }
1311  }
1312  }
1313 };
1314 
1315 //----------------------------------------------------------------------------
1316 // EnumType用TheolizerVersion用Switcher
1317 //----------------------------------------------------------------------------
1318 
1319 // ---<<< EnumType用TheolizerVersion用Switcher本体 >>>---
1320 
1321 template<class tBaseSerializer, class tVersionType, bool tIsRegister, TrackingMode tTrackingMode>
1322 struct Switcher
1323 <
1324  tBaseSerializer,
1325  tVersionType,
1326  tIsRegister,
1327  tTrackingMode,
1328  typename tVersionType::TheolizerEnumVersion
1329 >
1330 {
1331  typedef typename tVersionType::TheolizerTarget TheolizerTarget;
1332 
1333  // 保存
1334  static void save(tBaseSerializer& iSerializer, tVersionType& iInstance)
1335  {
1336  if (tTrackingMode == etmDefault)
1337  {
1338  iInstance.saveEnum(iSerializer, tVersionType::Theolizer::kLastVersionNo);
1339  }
1340  else
1341  {
1342  bool aIsSaved;
1343 //std::cout << "Switcher(EnumVersion) " << THEOLIZER_INTERNAL_TYPE_NAME(tVersionType) << "\n";
1344  SerializeInfo& aSerializeInfo=
1345  iSerializer.registerObject
1346  (
1347  iInstance.mTarget,
1348  typeid(iInstance.mTarget),
1349  tTrackingMode,
1350  &aIsSaved
1351  );
1352 
1353  // 型のTypeIndex取り出し
1354  std::size_t aTypeIndex = theolizer::internal::kInvalidSize;
1355  if (iSerializer.mCheckMode == theolizer::CheckMode::TypeCheckInData)
1356  {
1357  aTypeIndex = theolizer::internal::getTypeIndex<TheolizerTarget>();
1358  }
1359 
1360  // 開始/終了マーク処理
1361  BaseSerializer::AutoRestoreSaveStructure aAutoRestoreSaveStructure
1362  (
1363  iSerializer,
1364  emOrder,
1365  Structure::Pointee,
1366  aTypeIndex,
1367  aSerializeInfo.mObjectId,
1368  true
1369  );
1370 
1371  // 未保存の時のみ保存する
1372  if (!aIsSaved)
1373  {
1374  iSerializer.writePreElement();
1375  iInstance.saveEnum(iSerializer, tVersionType::Theolizer::kLastVersionNo);
1376  }
1377  }
1378  }
1379  // 回復
1380  static void load(tBaseSerializer& iSerializer, tVersionType& oInstance)
1381  {
1382  if (tTrackingMode == etmDefault)
1383  {
1384  oInstance.loadEnum(iSerializer, tVersionType::Theolizer::kLastVersionNo);
1385  }
1386  else
1387  {
1388  // 型のTypeIndex取り出し
1389  std::size_t aTypeIndex = theolizer::internal::kInvalidSize;
1390  if (iSerializer.mCheckMode == theolizer::CheckMode::TypeCheckInData)
1391  {
1392  aTypeIndex = theolizer::internal::getTypeIndex<TheolizerTarget>();
1393  }
1394 
1395  // 開始/終了マーク処理
1396  size_t aObjectId=kInvalidSize;
1397  BaseSerializer::AutoRestoreLoadStructure aAutoRestoreLoadStructure
1398  (
1399  iSerializer,
1400  emOrder,
1401  Structure::Pointee,
1402  aTypeIndex,
1403  &aObjectId
1404  );
1405 
1406  bool aIsLoaded;
1407  iSerializer.recoverObject
1408  (
1409  aObjectId,
1410  reinterpret_cast<void*&>(oInstance.mTarget),
1411  typeid(oInstance.mTarget),
1412  tTrackingMode,
1413  &aIsLoaded
1414  );
1415  // 未回復の時のみ回復する
1416  if (!aIsLoaded)
1417  {
1418  iSerializer.readPreElement();
1419  oInstance.loadEnum(iSerializer, tVersionType::Theolizer::kLastVersionNo);
1420  }
1421  }
1422  }
1423 };
1424 
1425 //----------------------------------------------------------------------------
1426 // プリミティブ型用Switcher
1427 //----------------------------------------------------------------------------
1428 
1429 // ---<<< Primitive用Switcher本体 >>>---
1430 // プリミティブへの参照の場合でも、save/loadPrimitiveにマッチする。
1431 // なので、参照の場合はここにマッチしないように条件を追加している。
1432 
1433 template<class tBaseSerializer,typename tPrimitiveType,bool tIsRegister,TrackingMode tTrackingMode>
1434 struct Switcher
1435 <
1436  tBaseSerializer,
1437  tPrimitiveType,
1438  tIsRegister,
1439  tTrackingMode,
1440  EnableIf<IsPrimitive<tPrimitiveType>::value>
1441 >
1442 {
1443  // 保存
1444  static void save(tBaseSerializer& iSerializer, tPrimitiveType& iInstance)
1445  {
1446  if (tTrackingMode == etmDefault)
1447  {
1448  iSerializer.savePrimitive(iInstance);
1449  }
1450  else
1451  {
1452  bool aIsSaved;
1453 //std::cout << "Switcher(Primitive) " << THEOLIZER_INTERNAL_TYPE_NAME(tPrimitiveType) << "\n";
1454  SerializeInfo& aSerializeInfo=
1455  iSerializer.registerObject
1456  (
1457  &iInstance,
1458  typeid(&iInstance),
1459  tTrackingMode,
1460  &aIsSaved
1461  );
1462 
1463  // 型のTypeIndex取り出し
1464  std::size_t aTypeIndex = theolizer::internal::kInvalidSize;
1465  if (iSerializer.mCheckMode == theolizer::CheckMode::TypeCheckInData)
1466  {
1467  aTypeIndex = theolizer::internal::getTypeIndex<tPrimitiveType>();
1468  }
1469 
1470  // 開始/終了マーク処理
1471  BaseSerializer::AutoRestoreSaveStructure aAutoRestoreSaveStructure
1472  (
1473  iSerializer,
1474  emOrder,
1475  Structure::Pointee,
1476  aTypeIndex,
1477  aSerializeInfo.mObjectId,
1478  true
1479  );
1480 
1481  // 未保存の時のみ保存する
1482  if (!aIsSaved)
1483  {
1484  iSerializer.writePreElement();
1485  iSerializer.savePrimitive(iInstance);
1486  }
1487  }
1488  }
1489  // 回復
1490  static void load(tBaseSerializer& iSerializer, tPrimitiveType& oInstance)
1491  {
1492  if (tTrackingMode == etmDefault)
1493  {
1494  iSerializer.loadPrimitive(oInstance);
1495  }
1496  else
1497  {
1498  // 型のTypeIndex取り出し
1499  std::size_t aTypeIndex = theolizer::internal::kInvalidSize;
1500  if (iSerializer.mCheckMode == theolizer::CheckMode::TypeCheckInData)
1501  {
1502  aTypeIndex = theolizer::internal::getTypeIndex<tPrimitiveType>();
1503  }
1504 
1505  // 開始/終了マーク処理
1506  size_t aObjectId=kInvalidSize;
1507  BaseSerializer::AutoRestoreLoadStructure aAutoRestoreLoadStructure
1508  (
1509  iSerializer,
1510  emOrder,
1511  Structure::Pointee,
1512  aTypeIndex,
1513  &aObjectId
1514  );
1515 
1516  bool aIsLoaded;
1517  tPrimitiveType* aPointer=&oInstance;
1518  iSerializer.recoverObject
1519  (
1520  aObjectId,
1521  reinterpret_cast<void*&>(aPointer),
1522  typeid(aPointer),
1523  tTrackingMode,
1524  &aIsLoaded
1525  );
1526  // 未回復の時のみ回復する
1527  if (!aIsLoaded)
1528  {
1529  iSerializer.readPreElement();
1530  iSerializer.loadPrimitive(oInstance);
1531  }
1532  }
1533  }
1534 };
1535 
1536 //----------------------------------------------------------------------------
1537 // TheolizerNonKeepStep<>用Switcher
1538 //----------------------------------------------------------------------------
1539 
1540 template
1541 <
1542  class tBaseSerializer,
1543  class tTheolizerNonKeepStep,
1544  bool tIsRegister,
1545  TrackingMode tTrackingMode
1546 >
1547 struct Switcher
1548 <
1549  tBaseSerializer,
1550  tTheolizerNonKeepStep,
1551  tIsRegister,
1552  tTrackingMode,
1553  EnableIf
1554  <
1555  IsTheolizerNonKeepStep<tTheolizerNonKeepStep>::value
1556  >
1557 >
1558 {
1559  // 保存
1560  static void save(tBaseSerializer& iSerializer, tTheolizerNonKeepStep& iInstance)
1561  {
1562  iInstance.template save<tIsRegister, tTrackingMode>(iSerializer);
1563  }
1564  // 回復
1565  static void load(tBaseSerializer& iSerializer, tTheolizerNonKeepStep& oInstance)
1566  {
1567  oInstance.template load<tIsRegister, tTrackingMode>(iSerializer);
1568  }
1569 };
1570 
1571 // ***************************************************************************
1572 // 保存/回復処理入口関数
1573 // インスタンスはできるだけ早期にconstを外す。
1574 // 内部処理でconstを残すと型のハンドリングがややこしいため。
1575 // ***************************************************************************
1576 
1577 //----------------------------------------------------------------------------
1578 // 派生Serializer抽出(ドライバー用)
1579 //----------------------------------------------------------------------------
1580 
1581 template<class tMidSerializer>
1582 struct MidSerializer
1583 {
1584  static MidSerializer& getInstance()
1585  {
1586  static MidSerializer instance;
1587  return instance;
1588  }
1589 };
1590 
1591 template<class tSerializer>
1592 int registerMidSerializer()
1593 {
1594  theolizer::internal::MidSerializer<typename tSerializer::MidSerializer>::getInstance();
1595  return 0;
1596 }
1597 
1598 #define THEOLIZER_INTERNAL_REGISTER_MID_SERIALIZER(dSerializer) \
1599  static int k##dSerializer THEOLIZER_INTERNAL_UNUSED= \
1600  theolizer::internal::registerMidSerializer<dSerializer<> >()
1601 
1602 //----------------------------------------------------------------------------
1603 // トップ・レベル/非トップ・レベル分岐と処理
1604 // 既にconstは外れていること
1605 //----------------------------------------------------------------------------
1606 
1607 // ---<<< プライマリ >>>---
1608 
1609 template
1610 <
1611  TrackingMode tTrackingMode,
1612  class tTheolizerVersion,
1613  class tSerializer,
1614  typename tType,
1615  class tEnable
1616 >
1617 struct BranchedProcess { };
1618 
1619 // ---<<< トップ・レベル >>>---
1620 
1621 template
1622 <
1623  TrackingMode tTrackingMode,
1624  class tTheolizerVersion,
1625  class tSerializer,
1626  typename tType
1627 >
1628 struct BranchedProcess
1629 <
1630  tTrackingMode,
1631  tTheolizerVersion,
1632  tSerializer,
1633  tType,
1634  EnableIf<tSerializer::kHasDestination>
1635 >
1636 {
1637  static void process
1638  (
1639  tSerializer& iSerializer,
1640  tType& ioInstance,
1641  char const* iName,
1642  char const* iFileName,
1643  size_t iLineNo
1644  )
1645  {
1646  // upVersionカウンタ・クリア
1647  theolizer::internal::getUpVersionCount()=0;
1648 //std::cout << "(0.1)UpVersionCount=" << theolizer::internal::getUpVersionCount()
1649 // << " " << THEOLIZER_INTERNAL_TYPE_NAME(tType) << std::endl;
1650 
1651  // 型情報取得中継クラス登録
1652  TypeFunctions<tSerializer> aTypeFunctions;
1653 
1654  // TypeInfoListへ登録
1655  RegisterType<tSerializer, tType, tTheolizerVersion>::getInstance();
1656 
1657  // エラー情報登録
1658  ApiBoundary aApiBoundary(&iSerializer.mAdditionalInfo);
1659  BaseSerializer::AutoRestoreSerializeInfo aAutoRestoreSerializeInfo
1660  (iSerializer, iName, 0, std::is_pointer<tType>::value, iFileName, iLineNo);
1661 
1662  // 例外の処理
1663  try
1664  {
1665  // エラーが発生していたら戻る
1666  iSerializer.checkError();
1667 
1668  // 保存/回復処理
1669  if (iSerializer.mIsSaver)
1670  {
1671  BaseSerializer::AutoRestoreSaveProcess
1672  aAutoRestoreSaveTop(iSerializer, getTypeIndex<tType>());
1673 
1674  // 保存処理呼び出し
1675  Switcher<BaseSerializer, tType, true, tTrackingMode>::save(iSerializer,ioInstance);
1676  }
1677  else
1678  {
1679  BaseSerializer::AutoRestoreLoadProcess
1680  aAutoRestoreLoadTop(iSerializer, getTypeIndex<tType>());
1681 
1682  // 回復処理呼び出し
1683  Switcher<BaseSerializer, tType, true, tTrackingMode>::load(iSerializer,ioInstance);
1684  }
1685  }
1686  catch (ErrorInfo&)
1687  {
1688  // 例外要求なら再throw
1689  if (!iSerializer.getNoThrowException())
1690  {
1691 throw;
1692  }
1693  }
1694  }
1695 };
1696 
1697 // ---<<< 非トップ・レベル >>>---
1698 
1699 template
1700 <
1701  TrackingMode tTrackingMode,
1702  class tTheolizerVersion,
1703  class tSerializer,
1704  typename tType
1705 >
1706 struct BranchedProcess
1707 <
1708  tTrackingMode,
1709  tTheolizerVersion,
1710  tSerializer,
1711  tType,
1712  EnableIf<!tSerializer::kHasDestination>
1713 >
1714 {
1715  static void process
1716  (
1717  tSerializer& iSerializer,
1718  tType& ioInstance,
1719  char const* iName,
1720  char const* iFileName,
1721  size_t iLineNo
1722  )
1723  {
1724  // upVersionCountのクリアと回復制御(processからの戻り時に元に戻す
1725  AutoRestore<unsigned> aUpVersionCount(getUpVersionCount(), 0);
1726 //std::cout << "(0.2)UpVersionCount=" << theolizer::internal::getUpVersionCount()
1727 // << " " << THEOLIZER_INTERNAL_TYPE_NAME(tType) << std::endl;
1728 
1729  // TypeInfoListへ登録
1730  RegisterType<tSerializer, tType, tTheolizerVersion>::getInstance();
1731 
1732  // エラー情報登録
1733  ApiBoundary aApiBoundary(&iSerializer.mAdditionalInfo);
1734  BaseSerializer::AutoRestoreSerializeInfo aAutoRestoreSerializeInfo
1735  (iSerializer, iName, 0, std::is_pointer<tType>::value, iFileName, iLineNo);
1736 
1737  // エラーが発生していたら戻る
1738  iSerializer.checkError();
1739 
1740  // 保存/回復処理
1741  if (iSerializer.mIsSaver)
1742  {
1743  iSerializer.writePreElement(true);
1744  BaseSerializer::AutoRestoreSaveProcess
1745  aAutoRestoreSaveTop(iSerializer, getTypeIndex<tType>());
1746  Switcher<BaseSerializer, tType, true, tTrackingMode>::save(iSerializer, ioInstance);
1747  }
1748  else
1749  {
1750  if (iSerializer.readPreElement(true))
1751  {
1752  BaseSerializer::AutoRestoreLoadProcess
1753  aAutoRestoreLoadTop(iSerializer, getTypeIndex<tType>());
1754  Switcher<BaseSerializer, tType, true, tTrackingMode>::load(iSerializer,ioInstance);
1755  }
1756  }
1757  }
1758 };
1759 
1760 //----------------------------------------------------------------------------
1761 // 保存/回復分岐処理
1762 //----------------------------------------------------------------------------
1763 
1764 // ---<<< const、もしくは、一時オブジェクト(右辺値) >>>---
1765 
1766 template
1767 <
1768  TrackingMode tTrackingMode,
1769  class tTheolizerVersion,
1770  class tSerializer,
1771  typename tType
1772 >
1773 void process
1774 (
1775  tSerializer& iSerializer,
1776  tType const& iInstance,
1777  char const* iName,
1778  char const* iFileName,
1779  size_t iLineNo
1780 )
1781 {
1782  THEOLIZER_INTERNAL_ASSERT(iSerializer.mIsSaver, "Can not load to const variable.(%1%)", iName);
1783 
1784  // const外し
1785  typedef typename RemoveCV<tType>::type Type;
1786 
1787  // 呼び出し
1788  // Cスタイル・キャストを意図的に使用している
1789  // 例えば、char const* array[10];のようなオブジェクトを保存する時、
1790  // constを解除しておかないと、後の処理でconst回避に苦労する。
1791  // しかし、const領域へのポインタ配列は、C++スタイル・キャストでは
1792  // constを解除できないため。
1793  BranchedProcess<tTrackingMode, tTheolizerVersion, tSerializer, Type>::
1794  process(iSerializer, (Type&)iInstance, iName, iFileName, iLineNo);
1795 }
1796 
1797 // ---<<< 通常のオブジェクト >>>---
1798 
1799 template
1800 <
1801  TrackingMode tTrackingMode,
1802  class tTheolizerVersion,
1803  class tSerializer,
1804  typename tType
1805 >
1806 void process
1807 (
1808  tSerializer& iSerializer,
1809  tType& ioInstance,
1810  char const* iName,
1811  char const* iFileName,
1812  size_t iLineNo
1813 )
1814 {
1815  BranchedProcess<tTrackingMode, tTheolizerVersion, tSerializer, tType>::
1816  process(iSerializer, ioInstance, iName, iFileName, iLineNo);
1817 }
1818 
1819 //############################################################################
1820 // End
1821 //############################################################################
1822 
1823 #endif // THEOLIZER_INTERNAL_DOXYGEN
1824 } // namespace internal
1825 } // namespace theolizer
1826 
1827 // ***************************************************************************
1828 // 警告抑止解除
1829 // ***************************************************************************
1830 
1831 #ifdef _MSC_VER
1832  #pragma warning(pop)
1833 #endif
1834 
1835 #endif // THEOLIZER_INTERNAL_CORE_SWITCHER_H
theolizer名前空間
Definition: base.h:53