Theolizer  Version.1.2.0
serializer for C++ / Do you want to update your classes easily ?
version_array.h
1 //############################################################################
2 // Theolizerライブラリの生配列用TheolizerVersion<>
3 // 他のTheolizerVersion<>と異なり、全ての配列用に1つのテンプレートで対応する
4 /*
5  © 2016 Theoride Technology (http://theolizer.com/) All Rights Reserved.
6  "Theolizer" is a registered trademark of Theoride Technology.
7 
8  "Theolizer" License
9  In the case where you are in possession of a valid “Theolizer” License,
10  you may use this file in accordance with the terms and conditions of
11  the use license determined by Theoride Technology.
12 
13  General Public License Version 3 ("GPLv3")
14  You may use this file in accordance with the terms and conditions of
15  GPLv3 published by Free Software Foundation.
16  Please confirm the contents of GPLv3 at https://www.gnu.org/licenses/gpl.txt .
17  A copy of GPLv3 is also saved in a LICENSE.TXT file.
18 
19  商用ライセンス
20  あなたが有効なTheolizer商用ライセンスを保持している場合、
21  セオライド テクノロジーの定める使用許諾書の条件に従って、
22  このファイルを取り扱うことができます。
23 
24  General Public License Version 3(以下GPLv3)
25  Free Software Foundationが公表するGPLv3の使用条件に従って、
26  あなたはこのファイルを取り扱うことができます。
27  GPLv3の内容を https://www.gnu.org/licenses/gpl.txt にて確認して下さい。
28  またGPLv3のコピーをLICENSE.TXTファイルにおいてます。
29 */
30 //############################################################################
31 
32 #if !defined(THEOLIZER_INTERNAL_VERSION_ARRAY_H)
33 #define THEOLIZER_INTERNAL_VERSION_ARRAY_H
34 
35 //############################################################################
36 // Begin
37 //############################################################################
38 
39 // ***************************************************************************
40 // 警告抑止
41 // ***************************************************************************
42 
43 #ifdef _MSC_VER
44  #pragma warning(push)
45  #pragma warning(disable:4127)
46 #endif
47 
48 namespace theolizer
49 {
50 namespace internal
51 {
52 #ifndef THEOLIZER_INTERNAL_DOXYGEN
53 
54 // ***************************************************************************
55 // 生配列の型定義
56 // Array<型, 要素数>にて生配列の型になる
57 // 下記2つは同じ定義である。
58 // theolizer::Array<int, 10, 20> aIntArray;
59 // int aIntArray[10][20];
60 // このテンプレートで配列の参照を下記のように定義することができる。
61 // theolizer::Array<int, 10>& aInt10;
62 // int (&aInt)[10];
63 // ***************************************************************************
64 
65 //----------------------------------------------------------------------------
66 // デバッグ・ツール
67 //----------------------------------------------------------------------------
68 
69 struct ArrayDebugBase
70 {
71  thread_local static unsigned mtIndent;
72  ArrayDebugBase() { }
73  ArrayDebugBase(unsigned)
74  {
75  mtIndent++;
76  }
77 };
78 
79 #if 0
80 template<typename... tTypes>
81 void outputArrayDebugImpl(tTypes...)
82 {
83 }
84 
85 template<typename tFirst, typename... tTypes>
86 void outputArrayDebugImpl(tFirst const& iFirst, tTypes const&... iTypes)
87 {
88  std::cout << std::string(ArrayDebugBase::mtIndent*2+2, ' ')
89  << "[" << &iFirst << "] "
90  << THEOLIZER_INTERNAL_TYPE_NAME(tFirst) << std::endl;
91  if (sizeof...(tTypes))
92  {
93  return outputArrayDebugImpl(iTypes...);
94  }
95 }
96 
97 template<typename... tTypes>
98 unsigned outputArrayDebug(std::string const& iTitle, tTypes const&... iTypes)
99 {
100  std::cout << std::string(ArrayDebugBase::mtIndent*2, ' ') << iTitle << std::endl;
101  if (sizeof...(tTypes))
102  {
103  outputArrayDebugImpl(iTypes...);
104  }
105  return 0;
106 }
107 
108 #define THEOLIZER_INTERNAL_DEBUG_ARRAY_BASE : public ArrayDebugBase
109 #define THEOLIZER_INTERNAL_DEBUG_ARRAY(...) ArrayDebugBase(outputArrayDebug(__VA_ARGS__)),
110 #define THEOLIZER_INTERNAL_DEBUG_ARRAY_END() (--ArrayDebugBase::mtIndent)
111 #else
112 #define THEOLIZER_INTERNAL_DEBUG_ARRAY_BASE
113 #define THEOLIZER_INTERNAL_DEBUG_ARRAY(...)
114 #define THEOLIZER_INTERNAL_DEBUG_ARRAY_END()
115 #endif
116 
117 //----------------------------------------------------------------------------
118 // 配列初期化用のインデックスのリスト生成
119 // IndicesHolder<0, 1, 2, ..., tIndices-1>を生成する
120 //----------------------------------------------------------------------------
121 
122 template<std::size_t... tIndices>
123 struct IndicesHolder
124 {
125  typedef IndicesHolder<tIndices..., sizeof...(tIndices)> Next;
126 };
127 
128 template<std::size_t tIndexCount>
129 struct MakeIndices
130 {
131  typedef typename MakeIndices<tIndexCount-1>::Type::Next Type;
132 };
133 
134 template<>
135 struct MakeIndices<0>
136 {
137  typedef IndicesHolder<> Type;
138 };
139 
140 //----------------------------------------------------------------------------
141 // ターゲット型取り出し
142 // クラスやenum(参照がついていない) TheolizerTarget
143 // そうでないなら、 tUnderlyingTypeの参照解除
144 //----------------------------------------------------------------------------
145 
146 template<typename tUnderlyingType>
147 struct GetTheolizerTarget
148 {
149  typedef typename tUnderlyingType::TheolizerTarget Type;
150 };
151 
152 template<typename tUnderlyingType>
153 struct GetTheolizerTarget< ::TheolizerNonKeepStep<tUnderlyingType, void> >
154 {
155  typedef tUnderlyingType Type;
156 };
157 
158 //----------------------------------------------------------------------------
159 // 型とサイズの異なる配列から、コンストラクトされる配列型
160 // 型には、基本型::TheolizerVersion<>が入る。
161 // 基本型がKeep-stepなクラスやenumの場合、
162 // 基本型::TheolizerVersion<, N+1>から基本型::TheolizerVersion<, N>
163 // をコントスラクト可能。
164 // 特記事項:
165 // 配列初期化子は、型変換後にリスト生成される。
166 // つまり、ArrayBodyの場合、
167 // mData{tType(iData[tIndices])...}となっていることになる
168 // そして、tType(これは基本型::TheolizerVersion<>)の同じバージョンからの
169 // コンストラクタへ与えられる。
170 // それがtType&引数の場合、tType(iData[tIndices])が一時オブジェクトで
171 // あるため、gccではエラーになる。
172 // そこで、version*.incの同じバージョンからのコンストラクタは
173 // tType const&引数のコピー・コンストラクタとする。
174 // TheolizerVersion<>内の参照で問題が出そうな気がする。
175 // ターゲットからのコンストラクタはターゲット内部の要素への参照
176 // 1つ1つがconstとなるため、問題が出る。
177 // しかし、同じバージョン同士の場合、TheolizerVersion<>全体への
178 // 参照がconstになるだけであり、中身は非constのままなので、
179 // 問題ない。
180 //----------------------------------------------------------------------------
181 
182 // ---<<< Keep-step(TheolizerVersion<>が指定されている) or Non-keep-stepの非最下位次元 >>>---
183 
184 template<typename tElementType, std::size_t tDim>
185 struct ArrayBody
186 {
187  tElementType mElements[tDim];
188 
189  // 通常のコンストラクタ
190  template<typename tArraySingleDimension, std::size_t... tIndices>
191  ArrayBody(tArraySingleDimension& iData, IndicesHolder<tIndices...>) :
192  mElements{iData[tIndices]...}
193  { }
194 
195  // デフォルト・コンストラクタ
196  // バージョンアップで削除された要素をバージョンダウン時に用意する時使用される
197  ArrayBody() : mElements{}
198  { }
199 
200  // 次元数減少対応用(1つの要素を先頭へムーブする)
201  ArrayBody(tElementType&& iData) :
202  mElements{std::move(iData)}
203  { }
204 };
205 
206 //----------------------------------------------------------------------------
207 // msvc 2015不具合対応
208 // 問題
209 // EnableIf<>内で関数を直接呼び出すとfalseと決めつけてしまい、
210 // 適切にコンパイルできない。
211 // →別クラス・テンプレートで間接的に処理すればOKだった。
212 // 他の対策も2016/02/11 12:30頃のコミットは実装している。
213 // コンストラクタから、mArrayBodyの初期化子を呼ぶ際に
214 // クラス・テンプレートを特殊化して分岐する方法。
215 //----------------------------------------------------------------------------
216 
217 template<unsigned tVersionNo, class tTheolizerVersion, class tEnable=void>
218 struct Judge
219 {
220  template<std::size_t... tDims>
221  struct Dimensions
222  {
223  static const bool kFulfil=false;
224  static const bool kHigher=false;
225  static const bool kLower =false;
226  };
227 };
228 template<unsigned tVersionNo, class tTheolizerVersion>
229 struct Judge<tVersionNo, tTheolizerVersion, typename tTheolizerVersion::TheolizerArrayVersion >
230 {
231  template<std::size_t... tDims>
232  struct Dimensions
233  {
234  static const bool kFulfil=tTheolizerVersion::isFulfil(tVersionNo, sizeof...(tDims)+1);
235  static const bool kHigher=tTheolizerVersion::isHigher(tVersionNo, sizeof...(tDims)+1);
236  static const bool kLower =tTheolizerVersion::isLower (tVersionNo, sizeof...(tDims)+1);
237  };
238 };
239 
240 //----------------------------------------------------------------------------
241 // 本体
242 // tUnderlyingTypeは、
243 // Non-keep-stepな型は 基本型& (参照があるので注意)
244 // Keep-stepな型は 基本型::TheolizerVersion<>
245 // VersionTypeは、自分自身のTheolizerVersion<>を定義する
246 // VersionElementは、配下のTheolizerVersion<>を定義する
247 // VersionArrayは、配下のTheolizerVersion<>の配列を定義する
248 //----------------------------------------------------------------------------
249 
250 template<typename tUnderlyingType, std::size_t... tDims>
251 struct ArrayManager
252 {
253 };
254 
255 // ---<<< 基本型のTheolizerVersion<>(プライマリー:Keep-step型用) >>>---
256 
257 template<typename tUnderlyingType>
258 struct ArrayManager<tUnderlyingType>
259 {
260  template<class tMidSerializer, unsigned tVersionNo>
261  struct TheolizerVersion THEOLIZER_INTERNAL_DEBUG_ARRAY_BASE
262  {
263  typedef void TheolizerArrayUnderlying; // Switcher<>分岐用
264  typedef tUnderlyingType UnderlyingType; // Switcher<>処理用
265 
266  // Switcher<>分岐用
267  struct Theolizer
268  {
269  static const bool kIsVersion=true;
270  static const bool kIsArray=true;
271  };
272 
273 // --- 型定義 ---
274 
275  // ユーザ定義配列の「基本型」
276  typedef typename GetTheolizerTarget<tUnderlyingType>::Type TheolizerTarget;
277 
278  // ユーザ定義配列用内部配列の型
279  typedef theolizer::internal::CoveredArray<TheolizerTarget> TargetCoveredArray;
280 
281 // --- 実体定義 ---
282 
283  tUnderlyingType mElement;
284 
285 // --- アクセス用関数 ---
286 
287  // 中身へのアクセスを提供する
288  typedef typename tUnderlyingType::AsElementOfArray AsElementOfArray;
289  AsElementOfArray& getAccess() {return mElement.getAccess();}
290  AsElementOfArray const& getAccess() const {return mElement.getAccess();}
291 
292  // 自分自身の配列を返却する(save/loadArrayへ渡すためと次元数削減時に使用)
293  tUnderlyingType& get() {return mElement;}
294 
295 // --- 構築用関数 ---
296 
297  // コンストラクタ(ターゲットから)
298  TheolizerVersion(TargetCoveredArray& iElement) :
299  THEOLIZER_INTERNAL_DEBUG_ARRAY(u8"KS :Target ", *this, iElement)
300  mElement(iElement.getElement())
301  { THEOLIZER_INTERNAL_DEBUG_ARRAY_END(); }
302 
303  // コンストラクタ(次バージョンから)
304  template<class tTheolizerVersion>
305  TheolizerVersion(tTheolizerVersion& iElement) :
306  THEOLIZER_INTERNAL_DEBUG_ARRAY(u8"KS :Next ", *this, iElement)
307  mElement(iElement.mElement)
308  { THEOLIZER_INTERNAL_DEBUG_ARRAY_END(); }
309 
310  // コンストラクタ(同バージョンから)
311  TheolizerVersion(TheolizerVersion& iElement) :
312  THEOLIZER_INTERNAL_DEBUG_ARRAY(u8"KS :Same ", *this, iElement)
313  mElement(iElement.mElement)
314  { THEOLIZER_INTERNAL_DEBUG_ARRAY_END(); }
315 
316  // ムーブ・コンストラクタ(同バージョンから)
317  TheolizerVersion(TheolizerVersion&& iElement) :
318  THEOLIZER_INTERNAL_DEBUG_ARRAY(u8"KS :Move ", *this, iElement)
319  mElement(std::move(iElement.mElement))
320  { THEOLIZER_INTERNAL_DEBUG_ARRAY_END(); }
321 
322  // デフォルト・コンストラクタ
323  TheolizerVersion() :
324  THEOLIZER_INTERNAL_DEBUG_ARRAY(u8"KS :Default ", *this)
325  mElement()
326  { THEOLIZER_INTERNAL_DEBUG_ARRAY_END(); }
327  };
328 };
329 
330 // ---<<< 基本型のTheolizerVersion<>(Non-keep-step型用) >>>---
331 
332 template<typename tPrimitiveType>
333 struct ArrayManager< ::TheolizerNonKeepStep<tPrimitiveType, void> >
334 {
335  typedef ::TheolizerNonKeepStep<tPrimitiveType, void> TheolizerNonKeepStep;
336 
337  template<class tMidSerializer, unsigned tVersionNo>
338  struct TheolizerVersion THEOLIZER_INTERNAL_DEBUG_ARRAY_BASE
339  {
340  typedef void TheolizerArrayUnderlying; // Switcher<>分岐用
341  typedef TheolizerNonKeepStep UnderlyingType; // Switcher<>処理用
342 
343  // Switcher<>分岐用
344  struct Theolizer
345  {
346  static const bool kIsVersion=true;
347  static const bool kIsArray=true;
348  };
349 
350 // --- 型定義 ---
351 
352  // ユーザ定義配列の基本型
353  typedef tPrimitiveType TheolizerTarget;
354 
355  // ユーザ定義配列用内部配列の型
356  typedef theolizer::internal::CoveredArray<TheolizerTarget> TargetCoveredArray;
357 
358 // --- 実体定義 ---
359 
360  TheolizerNonKeepStep mElement; // 実体
361 
362 // --- アクセス用関数 ---
363 
364  // 中身へのアクセスを提供する
365  typedef TheolizerNonKeepStep AsElementOfArray;
366  AsElementOfArray& getAccess() {return mElement;}
367  AsElementOfArray const& getAccess() const {return mElement;}
368 
369  // 自分自身の配列を返却する(save/loadArrayへ渡すためと次元数削減時に使用)
370  TheolizerNonKeepStep& get() {return mElement;}
371 
372 // --- 構築用関数 ---
373 
374  // コンストラクタ(ターゲットから)
375  TheolizerVersion(TargetCoveredArray& iElement) :
376  THEOLIZER_INTERNAL_DEBUG_ARRAY(u8"NKS:Target ", *this, iElement)
377  mElement(iElement.getElement())
378  { THEOLIZER_INTERNAL_DEBUG_ARRAY_END(); }
379 
380  // コンストラクタ(次バージョンから)
381  template<class tTheolizerVersion>
382  TheolizerVersion(tTheolizerVersion& iElement) :
383  THEOLIZER_INTERNAL_DEBUG_ARRAY(u8"NKS:Next ", *this, iElement)
384  mElement(iElement.mElement)
385  { THEOLIZER_INTERNAL_DEBUG_ARRAY_END(); }
386 
387  // コンストラクタ(同バージョンから)
388  TheolizerVersion(TheolizerVersion& iElement) :
389  THEOLIZER_INTERNAL_DEBUG_ARRAY(u8"NKS:Same ", *this, iElement)
390  mElement(iElement.mElement)
391  { THEOLIZER_INTERNAL_DEBUG_ARRAY_END(); }
392 
393  // ムーブ・コンストラクタ(同バージョンから)
394  TheolizerVersion(TheolizerVersion&& iElement) :
395  THEOLIZER_INTERNAL_DEBUG_ARRAY(u8"NKS:Move ", *this, iElement)
396  mElement(std::move(iElement.mElement))
397  { THEOLIZER_INTERNAL_DEBUG_ARRAY_END(); }
398 
399  // デフォルト・コンストラクタ
400  TheolizerVersion() :
401  THEOLIZER_INTERNAL_DEBUG_ARRAY(u8"NKS :Default ", *this)
402  mElement()
403  { THEOLIZER_INTERNAL_DEBUG_ARRAY_END(); }
404  };
405 };
406 
407 // ---<<< 配列のTheolizerVersion<>定義 >>>---
408 
409 template<typename tUnderlyingType, std::size_t tFirst, std::size_t... tDims>
410 struct ArrayManager<tUnderlyingType, tFirst, tDims...>
411 {
412  template<class tMidSerializer, unsigned tVersionNo>
413  struct TheolizerVersion THEOLIZER_INTERNAL_DEBUG_ARRAY_BASE
414  {
415  // Switcher<>分岐用
416  typedef void TheolizerArrayVersion;
417 
418  // Switcher<>分岐用
419  struct Theolizer
420  {
421  static const bool kIsVersion=true;
422  static const bool kIsArray=true;
423  };
424 
425 // --- 型定義 ---
426 
427  // ユーザ定義配列の「基本型」
428  typedef typename GetTheolizerTarget<tUnderlyingType>::Type TheolizerTarget;
429 
430  // ユーザ定義生配列の型(TypeInfoList登録へ使用する)
431  typedef theolizer::internal::Array<TheolizerTarget, tFirst, tDims...>
432  TargetArray;
433 
434  // ユーザ定義配列用内部配列の型
435  typedef theolizer::internal::CoveredArray<TheolizerTarget, tFirst, tDims...>
436  TargetCoveredArray;
437 
438  // 要素の型(VersionElement)とその配列の型(VersionArray)
439  typedef typename ArrayManager<tUnderlyingType, tDims...>::template
440  TheolizerVersion<tMidSerializer, tVersionNo> VersionElement;
441  typedef VersionElement VersionArray[tFirst];
442 
443  // アクセス用の型(AsElementOfArray:自分自身、ElementType:要素のAsElementOfArray)
444  typedef TheolizerVersion AsElementOfArray;
445  typedef typename ArrayManager<tUnderlyingType, tDims...>::template
446  TheolizerVersion<tMidSerializer, tVersionNo>::AsElementOfArray ElementType;
447 
448 // --- 実体定義 ---
449 
450  // 配列保持領域
451  ArrayBody<VersionElement, tFirst> mArrayBody;
452 
453 // --- アクセス用関数 ---
454 
455  // 要素数を返却する
456  static std::size_t size() {return tFirst;}
457 
458  // 指定要素へのアクセスを提供する
459  ElementType& operator[](std::size_t iIndex)
460  {return mArrayBody.mElements[iIndex].getAccess();}
461 
462  ElementType const& operator[](std::size_t iIndex) const
463  {return mArrayBody.mElements[iIndex].getAccess();}
464 
465  // 自分自身を返却する
466  AsElementOfArray& getAccess()
467  {return *this;}
468 
469  // 自分自身を配列として返却する(save/loadArrayへ渡すためと次元数削減時に使用)
470  VersionArray& get() {return mArrayBody.mElements;}
471 
472 // --- 構築用関数 ---
473 
474  // コンストラクタ(ターゲットから:入り口の次元)
475  TheolizerVersion(TargetArray& iTargetArray) :
476  THEOLIZER_INTERNAL_DEBUG_ARRAY(u8"---:Entry ", *this, iTargetArray)
477  mArrayBody(reinterpret_cast<TargetCoveredArray&>(iTargetArray).getElements(),
478  typename MakeIndices<tFirst>::Type())
479  { THEOLIZER_INTERNAL_DEBUG_ARRAY_END(); }
480 
481  // コンストラクタ(ターゲットから:内側の次元)
482  TheolizerVersion(TargetCoveredArray& iTargetCoveredArray) :
483  THEOLIZER_INTERNAL_DEBUG_ARRAY(u8"---:Inner ", *this, iTargetCoveredArray)
484  mArrayBody(iTargetCoveredArray.getElements(),
485  typename MakeIndices<tFirst>::Type())
486  { THEOLIZER_INTERNAL_DEBUG_ARRAY_END(); }
487 
488  // コンストラクタ(同バージョンから)
489  TheolizerVersion(TheolizerVersion& iTheolizerVersion) :
490  THEOLIZER_INTERNAL_DEBUG_ARRAY(u8"---:Same ", *this, iTheolizerVersion)
491  mArrayBody(iTheolizerVersion.mArrayBody)
492  { THEOLIZER_INTERNAL_DEBUG_ARRAY_END(); }
493 
494  // ムーブ・コンストラクタ(同バージョンから)
495  TheolizerVersion(TheolizerVersion&& iTheolizerVersion) :
496  THEOLIZER_INTERNAL_DEBUG_ARRAY(u8"---:Move ", *this, iTheolizerVersion)
497  mArrayBody(std::move(iTheolizerVersion.mArrayBody))
498  { THEOLIZER_INTERNAL_DEBUG_ARRAY_END(); }
499 
500  // デフォルト・コンストラクタ
501  TheolizerVersion() :
502  THEOLIZER_INTERNAL_DEBUG_ARRAY(u8"---:Default ", *this)
503  mArrayBody()
504  { THEOLIZER_INTERNAL_DEBUG_ARRAY_END(); }
505 
506 // --- 次元数/要素数変更対応用関数定義 ---
507 
508  // 指定バージョン、かつ、指定次元であることを判定する
509  constexpr static bool isFulfil(unsigned iVersionNo, std::size_t iDimsCount)
510  {
511  return ((iVersionNo == tVersionNo) && (iDimsCount == (sizeof...(tDims)+1)));
512  }
513 
514  // 指定バージョン、かつ、指定次元より大きい次元であることを判定する
515  constexpr static bool isHigher(unsigned iVersionNo, std::size_t iDimsCount)
516  {
517  return ((iVersionNo == tVersionNo) && (iDimsCount < (sizeof...(tDims)+1)));
518  }
519 
520  // 指定バージョン、かつ、指定次元より小さい次元であることを判定する
521  constexpr static bool isLower(unsigned iVersionNo, std::size_t iDimsCount)
522  {
523  return ((iVersionNo == tVersionNo) && (iDimsCount > (sizeof...(tDims)+1)));
524  }
525 
526  // 前バージョンとの共通する要素数計算(前バージョンのコンストラクタから呼ばれる)
527  constexpr static const std::size_t getInitCount(
528  std::size_t iDstFirst, std::size_t iDstDimsCount)
529  {
530  return ((iDstDimsCount+1) <= ((sizeof...(tDims))+1))?
531  ((iDstFirst<tFirst)?iDstFirst:tFirst)
532  :
533  1;
534  }
535 
536  // 指定の(低)次元のTheolizerVersionを取り出す(クラス外で部分特殊化している)
537  template<class tTheolizerVersion, class tEnable=void>
538  struct GetTheolizerVersion
539  {
540  typedef VersionArray VersionArray_t;
541  static VersionArray_t& getLower(TheolizerVersion& iTheolizerVersion)
542  {
543  return iTheolizerVersion.get();
544  }
545  };
546 
547  // 注意事項
548  // 下記ヘルパー・クラスを作り、記述を簡略化しようとしたところ、
549  // MSVC 2015で"fatal error C1001"が発生する。
550  #if 0
551  // Judgeクラス展開用ヘルパー
552  template<class tTheolizerVersion2>
553  using JudgeVersion=typename Judge<tVersionNo+1, tTheolizerVersion2>::
554  template Dimensions<tDims...>;
555  #endif
556 
557  // コンストラクタ(次バージョンの同一次元から)
558  template
559  <
560  class tTheolizerVersion,
561  THEOLIZER_INTERNAL_OVERLOAD
562  (
563  (Judge<tVersionNo+1, tTheolizerVersion>::template Dimensions<tDims...>::kFulfil)
564  )
565  >
566  TheolizerVersion(tTheolizerVersion& iTheolizerVersion) :
567  THEOLIZER_INTERNAL_DEBUG_ARRAY(u8"---:Next-same ", *this, iTheolizerVersion)
568  mArrayBody(iTheolizerVersion.mArrayBody.mElements,
569  typename MakeIndices<
570  tTheolizerVersion::getInitCount(tFirst, sizeof...(tDims))
571  >::Type())
572  { THEOLIZER_INTERNAL_DEBUG_ARRAY_END(); }
573 
574  // コンストラクタ(次バージョンの上位次元から)
575  template
576  <
577  class tTheolizerVersion,
578  THEOLIZER_INTERNAL_OVERLOAD
579  (
580  (Judge<tVersionNo+1, tTheolizerVersion>::template Dimensions<tDims...>::kHigher)
581  )
582  >
583  TheolizerVersion(tTheolizerVersion& iTheolizerVersion) :
584  THEOLIZER_INTERNAL_DEBUG_ARRAY(u8"---:Next-upper", *this, iTheolizerVersion)
585  mArrayBody(tTheolizerVersion::template
586  GetTheolizerVersion<TheolizerVersion>::getLower(iTheolizerVersion),
587  //↑現次元と同じ次元の次バージョンのTheolizerVersion<>を取り出す
588  typename MakeIndices<
589  tTheolizerVersion::getInitCount(tFirst, sizeof...(tDims))
590  >::Type())
591  { THEOLIZER_INTERNAL_DEBUG_ARRAY_END(); }
592 
593  // コンストラクタ(次バージョンの下位次元から)
594  template
595  <
596  class tTheolizerVersion,
597  THEOLIZER_INTERNAL_OVERLOAD
598  (
599  (Judge<tVersionNo+1, tTheolizerVersion>::template Dimensions<tDims...>::kLower)
600  )
601  >
602  TheolizerVersion(tTheolizerVersion& iTheolizerVersion) :
603  THEOLIZER_INTERNAL_DEBUG_ARRAY(u8"---:Next-lower", *this, iTheolizerVersion)
604  mArrayBody(VersionElement(iTheolizerVersion))
605  { THEOLIZER_INTERNAL_DEBUG_ARRAY_END(); }
606  };
607 };
608 
609 // ---<<< 指定(低)次元のTheolizerVersionを取り出すための特殊化 >>>---
610 // このArrayManagerは次バージョン側である
611 
612 template<typename tUnderlyingType, std::size_t tFirst, std::size_t... tDims>
613 template<class tMidSerializer, unsigned tVersionNo>
614 template<class tTheolizerVersion>
615 struct ArrayManager<tUnderlyingType, tFirst, tDims...>::
616  TheolizerVersion<tMidSerializer, tVersionNo>::
617  GetTheolizerVersion<tTheolizerVersion, typename std::enable_if<
618  Judge<tVersionNo-1, tTheolizerVersion, void>::template
619  Dimensions<tDims...>::kLower>::type>
620 {
621  typedef typename ArrayManager<tUnderlyingType, tDims...>::template
622  TheolizerVersion<tMidSerializer, tVersionNo> LowerTheolizerVersion;
623  typedef typename LowerTheolizerVersion::template
624  GetTheolizerVersion<tTheolizerVersion>::VersionArray_t VersionArray_t;
625  static VersionArray_t& getLower(TheolizerVersion<tMidSerializer,tVersionNo>& iTheolizerVersion)
626  {
627  return LowerTheolizerVersion::template
628  GetTheolizerVersion<tTheolizerVersion>::
629  getLower(iTheolizerVersion.mArrayBody.mElements[0]);
630  }
631 };
632 
633 //############################################################################
634 // End
635 //############################################################################
636 
637 #endif // THEOLIZER_INTERNAL_DOXYGEN
638 } // namespace internal
639 } // namespace theolizer
640 
641 // ***************************************************************************
642 // 警告抑止解除
643 // ***************************************************************************
644 
645 #ifdef _MSC_VER
646  #pragma warning(pop)
647 #endif
648 
649 #endif // THEOLIZER_INTERNAL_VERSION_ARRAY_H
theolizer名前空間
Definition: base.h:53