Solution46
CArray.hpp
[詳解]
1 //=============================================================================
2 /// @file
3 /// 配列クラス実装ヘッダファイル
4 ///
5 /// 配列クラス実装ヘッダファイルです。
6 ///
7 /// $Id: CArray.hpp 245 2019-03-20 15:03:41Z admin $
8 /// $Date: 2019-03-21 00:03:41 +0900 (2019/03/21 (木)) $
9 /// $Author: admin $
10 ///
11 /// @attention なし
12 
13 #pragma once
14 #pragma managed( push, off )
15 
16 //=============================================================================
17 // インクルードファイル
18 #include <CArray.h>
19 #include <algorithm>
20 
21 //=============================================================================
22 // 共通ライブラリ名前空間
23 namespace LibCommon {
24  //=========================================================================
25  // 配列クラス
26  //=========================================================================
27  // 構築子と解体子
28  //-------------------------------------------------------------------------
29  // コンストラクタ
30  template< typename Type >
32  // メンバ変数初期化
33  : m_pBuffer( nullptr )
34  , m_nSize( 0 )
35  , m_nCount( 0 )
36  {}
37 
38  //-------------------------------------------------------------------------
39  // コンストラクタ
40  template< typename Type >
41  CArray< Type >::CArray( Type const& rElement ) noexcept
42  // 移譲コンストラクタ
43  : CArray()
44  {
45  // コピーする
46  Copy( rElement );
47  }
48 
49  //-------------------------------------------------------------------------
50  // コンストラクタ
51  template< typename Type >
52  CArray< Type >::CArray( Type const* pBuffer, int nCount ) noexcept
53  // 移譲コンストラクタ
54  : CArray()
55  {
56  // コピーする
57  Copy( pBuffer, nCount );
58  }
59 
60  //-------------------------------------------------------------------------
61  // コンストラクタ
62  template< typename Type >
63  CArray< Type >::CArray( std::initializer_list< Type const > const& rcInitializer ) noexcept
64  // 移譲コンストラクタ
65  : CArray()
66  {
67  // コピーする
68  Copy( rcInitializer );
69  }
70 
71  //-------------------------------------------------------------------------
72  // コピーコンストラクタ
73  template< typename Type >
74  CArray< Type >::CArray( CArray const& rcInstance ) noexcept
75  // 移譲コンストラクタ
76  : CArray()
77  {
78  // コピーする
79  Copy( rcInstance );
80  }
81 
82  //-------------------------------------------------------------------------
83  // ムーブコンストラクタ
84  template< typename Type >
85  CArray< Type >::CArray( CArray< Type >&& rcInstance ) noexcept
86  // 移譲コンストラクタ
87  : CArray()
88  {
89  // ムーブする
90  Move( std::move( rcInstance ) );
91  }
92 
93  //-------------------------------------------------------------------------
94  // デストラクタ
95  template< typename Type >
97  // クリアする
98  Clear();
99  }
100 
101  //=========================================================================
102  // 公開演算子オーバーロード関数
103  //-------------------------------------------------------------------------
104  // コピー代入演算子オーバーロード関数
105  template< typename Type >
106  CArray< Type >& CArray< Type >::operator=( CArray const& rcInstance ) noexcept {
107  // コピーする
108  Copy( rcInstance );
109 
110  // インスタンス参照を返す
111  return *this;
112  }
113 
114  //-------------------------------------------------------------------------
115  // ムーブ代入演算子オーバーロード関数
116  template< typename Type >
117  CArray< Type >& CArray< Type >::operator=( CArray&& rcInstance ) noexcept {
118  // ムーブする
119  Move( std::move( rcInstance ) );
120 
121  // インスタンス参照を返す
122  return *this;
123  }
124 
125  //-------------------------------------------------------------------------
126  // 代入演算子オーバーロード関数
127  template< typename Type >
128  CArray< Type >& CArray< Type >::operator=( Type const& rElement ) noexcept {
129  // コピーする
130  Copy( rElement );
131 
132  // インスタンス参照を返す
133  return *this;
134  }
135 
136  //-------------------------------------------------------------------------
137  // 代入演算子オーバーロード関数
138  template< typename Type >
139  CArray< Type >& CArray< Type >::operator=( std::initializer_list< Type const > const& rcInitializer ) noexcept {
140  // コピーする
141  Copy( rcInitializer );
142 
143  // インスタンス参照を返す
144  return *this;
145  }
146 
147  //-------------------------------------------------------------------------
148  // 加算代入演算子オーバーロード関数
149  template< typename Type >
150  CArray< Type >& CArray< Type >::operator+=( CArray const& rcInstance ) noexcept {
151  // 追加する
152  Append( rcInstance );
153 
154  // インスタンス参照を返す
155  return *this;
156  }
157 
158  //-------------------------------------------------------------------------
159  // 加算代入演算子オーバーロード関数
160  template< typename Type >
161  CArray< Type >& CArray< Type >::operator+=( Type const& rElement ) noexcept {
162  // 追加する
163  Append( rElement );
164 
165  // インスタンス参照を返す
166  return *this;
167  }
168 
169  //-------------------------------------------------------------------------
170  // 加算代入演算子オーバーロード関数
171  template< typename Type >
172  CArray< Type >& CArray< Type >::operator+=( std::initializer_list< Type const > const& rcInitializer ) noexcept {
173  // 追加する
174  Append( rcInitializer );
175 
176  // インスタンス参照を返す
177  return *this;
178  }
179 
180  //-------------------------------------------------------------------------
181  // 配列添字演算子オーバーロード関数
182  template< typename Type >
183  Type& CArray< Type >::operator[]( int nIndex ) noexcept {
184  // 静的配列要素
185  static Type element;
186 
187  // 処理ブロック
188  Type* result = &element;
189  do {
190  // インデックスを調べる
191  if ( ( 0 > nIndex ) || ( m_nCount <= nIndex ) ) {
192  // 失敗!
193  break;
194  }
195 
196  // 成功!
197  result = &m_pBuffer[ nIndex ];
198  } while ( false );
199 
200  // 実行結果を返す
201  return *result;
202  }
203 
204  //=========================================================================
205  // 公開関数
206  //-------------------------------------------------------------------------
207  // クリア関数
208  template< typename Type >
209  void CArray< Type >::Clear() noexcept {
210  // バッファを削除する
211  delete[] m_pBuffer;
212 
213  // メンバ変数を初期化する
214  m_pBuffer = nullptr;
215  m_nSize = 0;
216  m_nCount = 0;
217  }
218 
219  //-------------------------------------------------------------------------
220  // バッファ作成関数
221  template< typename Type >
222  bool CArray< Type >::CreateBuffer( int nSize ) noexcept {
223  // 処理ブロック
224  bool result = false;
225  do {
226  // バッファサイズを調べる
227  if ( m_nCount > nSize ) {
228  // 失敗!
229  break;
230  }
231  // バッファサイズを調べる
232  else if ( m_nSize != nSize ) {
233  // 新規バッファを作成する
234  Type* pNewBuffer = new Type[ nSize ];
235  if ( nullptr == pNewBuffer ) {
236  // 失敗!
237  break;
238  }
239  // 巡回する
240  else for ( int nIndex = 0; m_nCount > nIndex; ++nIndex ) {
241  // 配列要素をコピーする
242  pNewBuffer[ nIndex ] = m_pBuffer[ nIndex ];
243  }
244 
245  // 巡回する
246  for ( int nIndex = m_nCount; nSize > nIndex; ++nIndex ) {
247  // 配列要素をクリアする
248  ::memset( &pNewBuffer[ nIndex ], 0, sizeof( Type ) );
249  }
250 
251  // 既存バッファを削除する
252  delete[] m_pBuffer;
253 
254  // バッファポインタとバッファサイズを設定する
255  m_pBuffer = pNewBuffer;
256  m_nSize = nSize;
257  }
258 
259  // 成功!
260  result = true;
261  } while ( false );
262 
263  // 実行結果を返す
264  return result;
265  }
266 
267  //-------------------------------------------------------------------------
268  // バッファサイズ更新関数
269  template< typename Type >
270  bool CArray< Type >::UpdateBuffer( int nCount ) noexcept {
271  // 処理ブロック
272  bool result = false;
273  do {
274  // 配列要素数とバッファサイズを比較する
275  if ( m_nSize < nCount ) {
276  // 終端配列要素分を追加したセグメント単位のバッファサイズを取得する
277  int nSize = ( ( nCount + GetSegmentSize() ) / GetSegmentSize() * GetSegmentSize() );
278 
279  // バッファを作成する
280  if ( !CreateBuffer( nSize ) ) {
281  // 失敗!
282  break;
283  }
284  }
285 
286  // 成功!
287  result = true;
288  } while ( false );
289 
290  // 実行結果を返す
291  return result;
292  }
293 
294  //-------------------------------------------------------------------------
295  // バッファサイズコンパクト化関数
296  template< typename Type >
298  // 処理ブロック
299  bool result = false;
300  do {
301  // バッファサイズとバッファカウントを比較する
302  if ( m_nSize > m_nCount ) {
303  // バッファを作成する
304  if ( !CreateBuffer( m_nCount ) ) {
305  // 失敗!
306  break;
307  }
308  }
309 
310  // 成功!
311  result = true;
312  } while ( false );
313 
314  // 実行結果を返す
315  return result;
316  }
317 
318  //-------------------------------------------------------------------------
319  // コピー関数
320  template< typename Type >
321  bool CArray< Type >::Copy( CArray const& rcInstance ) noexcept {
322  // クリアする
323  Clear();
324 
325  // 挿入する
326  return Insert( 0, rcInstance );
327  }
328 
329  //-------------------------------------------------------------------------
330  // コピー関数
331  template< typename Type >
332  bool CArray< Type >::Copy( Type const& rElement ) noexcept {
333  // クリアする
334  Clear();
335 
336  // 挿入する
337  return Insert( 0, rElement );
338  }
339 
340  //-------------------------------------------------------------------------
341  // コピー関数
342  template< typename Type >
343  bool CArray< Type >::Copy( Type const* pBuffer, int nCount ) noexcept {
344  // クリアする
345  Clear();
346 
347  // 挿入する
348  return Insert( 0, pBuffer, nCount );
349  }
350 
351  //-------------------------------------------------------------------------
352  // コピー関数
353  template< typename Type >
354  bool CArray< Type >::Copy( std::initializer_list< Type const > const& rcInitializer ) noexcept {
355  // クリアする
356  Clear();
357 
358  // 挿入する
359  return Insert( 0, rcInitializer );
360  }
361 
362  //-------------------------------------------------------------------------
363  // ムーブ関数
364  template< typename Type >
365  bool CArray< Type >::Move( CArray< Type >&& rcInstance ) noexcept {
366  // 処理ブロック
367  bool result = false;
368  do {
369  // クリアする
370  Clear();
371 
372  // メンバ変数をコピーする
373  m_pBuffer = rcInstance.m_pBuffer;
374  m_nSize = rcInstance.m_nSize;
375  m_nCount = rcInstance.m_nCount;
376 
377  // ムーブ元インスタンスのメンバ変数を初期化する
378  rcInstance.m_pBuffer = nullptr;
379  rcInstance.m_nSize = 0;
380  rcInstance.m_nCount = 0;
381 
382  // 成功!
383  result = true;
384  } while ( false );
385 
386  // 実行結果を返す
387  return result;
388  }
389 
390  //-------------------------------------------------------------------------
391  // 追加関数
392  template< typename Type >
393  bool CArray< Type >::Append( CArray const& rcInstance ) noexcept {
394  // 挿入する
395  return Insert( m_nCount, rcInstance );
396  }
397 
398  //-------------------------------------------------------------------------
399  // 追加関数
400  template< typename Type >
401  bool CArray< Type >::Append( Type const& rElement ) noexcept {
402  // 挿入する
403  return Insert( m_nCount, rElement );
404  }
405 
406  //-------------------------------------------------------------------------
407  // 追加関数
408  template< typename Type >
409  bool CArray< Type >::Append( Type const* pBuffer, int nCount ) noexcept {
410  // 挿入する
411  return Insert( m_nCount, pBuffer, nCount );
412  }
413 
414  //-------------------------------------------------------------------------
415  // 追加関数
416  template< typename Type >
417  bool CArray< Type >::Append( std::initializer_list< Type const > const& rcInitializer ) noexcept {
418  // 挿入する
419  return Insert( m_nCount, rcInitializer );
420  }
421 
422  //-------------------------------------------------------------------------
423  // 挿入関数
424  template< typename Type >
425  bool CArray< Type >::Insert( int nIndex, CArray const& rcInstance ) noexcept {
426  // 挿入する
427  return Insert( nIndex, rcInstance.m_pBuffer, rcInstance.m_nCount );
428  }
429 
430  //-------------------------------------------------------------------------
431  // 挿入関数
432  template< typename Type >
433  bool CArray< Type >::Insert( int nIndex, Type const& rElement ) noexcept {
434  // 挿入する
435  return Insert( nIndex, &rElement, 1 );
436  }
437 
438  //-------------------------------------------------------------------------
439  // 挿入関数
440  template< typename Type >
441  bool CArray< Type >::Insert( int nIndex, Type const* pBuffer, int nCount ) noexcept {
442  // 処理ブロック
443  bool result = false;
444  do {
445  // バッファポインタを調べる
446  if ( nullptr == pBuffer ) {
447  // 失敗!
448  break;
449  }
450  // インデックスを調べる
451  else if ( ( 0 > nIndex ) || ( m_nCount < nIndex ) ) {
452  // 失敗!
453  break;
454  }
455  // 配列要素数を調べる
456  else if ( 0 > nCount ) {
457  // 失敗!
458  break;
459  }
460  // バッファサイズを更新する
461  else if ( !UpdateBuffer( m_nCount + nCount ) ) {
462  // 失敗!
463  break;
464  }
465 
466  // 移動配列要素数を取得する
467  int nMove = ( m_nCount - nIndex );
468  if ( 0 < nMove ) {
469  // 巡回する
470  Type* pDst = &m_pBuffer[ m_nCount + nCount - 1 ];
471  Type const* pSrc = &m_pBuffer[ m_nCount - 1 ];
472  for ( ; 0 < nMove; --nMove ) {
473  // 配列要素をコピーする
474  *pDst-- = *pSrc--;
475  }
476  }
477 
478  // 配列要素数を更新する
479  m_nCount += nCount;
480 
481  // 巡回する
482  Type const* pSrc = pBuffer;
483  Type* pDst = &m_pBuffer[ nIndex ];
484  for ( ; 0 < nCount; --nCount ) {
485  // 配列要素をコピーする
486  *pDst++ = *pSrc++;
487  }
488 
489  // 成功!
490  result = true;
491  } while ( false );
492 
493  // 実行結果を返す
494  return result;
495  }
496 
497  //-------------------------------------------------------------------------
498  // 挿入関数
499  template< typename Type >
500  bool CArray< Type >::Insert( int nIndex, std::initializer_list< Type const > const& rcInitializer ) noexcept {
501  // 処理ブロック
502  bool result = false;
503  do {
504  // 巡回する
505  for ( auto pcIter = rcInitializer.begin();; ++pcIter ) {
506  // イテレータを調べる
507  if ( rcInitializer.end() == pcIter ) {
508  // 成功!
509  result = true;
510  break;
511  }
512 
513  // 挿入する
514  if ( !Insert( nIndex++, *pcIter ) ) {
515  // 失敗!
516  break;
517  }
518  }
519  } while ( false );
520 
521  // 実行結果を返す
522  return result;
523  }
524 
525  //-------------------------------------------------------------------------
526  // 削除関数
527  template< typename Type >
528  bool CArray< Type >::Remove() noexcept {
529  // 削除する
530  return Remove( m_nCount - 1 );
531  }
532 
533  //-------------------------------------------------------------------------
534  // 削除関数
535  template< typename Type >
536  bool CArray< Type >::Remove( int nIndex ) noexcept {
537  // 削除する
538  return Remove( nIndex, 1 );
539  }
540 
541  //-------------------------------------------------------------------------
542  // 削除関数
543  template< typename Type >
544  bool CArray< Type >::Remove( int nIndex, int nCount ) noexcept {
545  // 処理ブロック
546  bool result = false;
547  do {
548  // インデックスを調べる
549  if ( ( 0 > nIndex ) || ( m_nCount <= nIndex ) ) {
550  // 失敗!
551  break;
552  }
553  // 配列要素数を調べる
554  else if ( ( m_nCount - nIndex ) < nCount ) {
555  // 失敗!
556  break;
557  }
558 
559  // 移動配列要素数を取得する
560  int nMove = ( m_nCount - nIndex - nCount );
561  if ( 0 < nMove ) {
562  // 巡回する
563  for ( ; 0 < nMove; --nMove, ++nIndex ) {
564  // 配列要素をコピーする
565  m_pBuffer[ nIndex ] = m_pBuffer[ nIndex + nCount ];
566  }
567  }
568 
569  // 巡回する
570  for ( ; m_nCount > nIndex; ++nIndex ) {
571  // 配列要素をクリアする
572  ::memset( &m_pBuffer[ nIndex ], 0, sizeof( Type ) );
573  }
574 
575  // 配列要素数を更新する
576  m_nCount -= nCount;
577 
578  // 成功!
579  result = true;
580  } while ( false );
581 
582  // 実行結果を返す
583  return result;
584  }
585 
586  //-------------------------------------------------------------------------
587  // 取得関数
588  template< typename Type >
589  bool CArray< Type >::Get( int nIndex, Type& rElement ) const noexcept {
590  // 処理ブロック
591  bool result = false;
592  do {
593  // インデックスを調べる
594  if ( ( 0 > nIndex ) || ( m_nCount <= nIndex ) ) {
595  // 失敗!
596  break;
597  }
598 
599  // 配列要素を取得する
600  rElement = m_pBuffer[ nIndex ];
601 
602  // 成功!
603  result = true;
604  } while ( false );
605 
606  // 実行結果を返す
607  return result;
608  }
609 
610  //-------------------------------------------------------------------------
611  // 設定関数
612  template< typename Type >
613  bool CArray< Type >::Set( int nIndex, Type const& rElement ) noexcept {
614  // 処理ブロック
615  bool result = false;
616  do {
617  // インデックスを調べる
618  if ( ( 0 > nIndex ) || ( m_nCount <= nIndex ) ) {
619  // 失敗!
620  break;
621  }
622 
623  // 配列要素を設定する
624  m_pBuffer[ nIndex ] = rElement;
625 
626  // 成功!
627  result = true;
628  } while ( false );
629 
630  // 実行結果を返す
631  return result;
632  }
633 
634  //-------------------------------------------------------------------------
635  // 検索関数
636  template< typename Type >
637  int CArray< Type >::Find( Type const& rElement ) const noexcept {
638  // 処理ブロック
639  int result = -1;
640  do {
641  // 巡回する
642  for ( int nIndex = 0; m_nCount > nIndex; ++nIndex ) {
643  // 配列要素を調べる
644  if ( Compare( rElement, m_pBuffer[ nIndex ] ) ) {
645  // 成功!
646  result = nIndex;
647  break;
648  }
649  }
650  } while ( false );
651 
652  // 実行結果を返す
653  return result;
654  }
655 
656  //-------------------------------------------------------------------------
657  // 比較関数
658  template< typename Type >
659  bool CArray< Type >::Compare( Type const& rElement1, Type const& rElement2 ) const noexcept {
660  // 処理ブロック
661  bool result = false;
662  do {
663  // 巡回する
664  for ( int nIndex = 0;; ++nIndex ) {
665  // インデックスを調べる
666  if ( sizeof( Type ) <= nIndex ) {
667  // 成功!
668  result = true;
669  break;
670  }
671  // バイトデータを調べる
672  else if ( reinterpret_cast< char const* >( &rElement1 )[ nIndex ] != reinterpret_cast< char const* >( &rElement2 )[ nIndex ] ) {
673  // 失敗!
674  break;
675  }
676  }
677  } while ( false );
678 
679  // 実行結果を返す
680  return result;
681  }
682 
683  //-------------------------------------------------------------------------
684  // プッシュ関数
685  template< typename Type >
686  bool CArray< Type >::Push( Type const& rElement ) noexcept {
687  // 追加する
688  return Append( rElement );
689  }
690 
691  //-------------------------------------------------------------------------
692  // プッシュ関数
693  template< typename Type >
694  bool CArray< Type >::Push( Type const* pBuffer, int nCount ) noexcept {
695  // 追加する
696  return Append( pBuffer, nCount );
697  }
698 
699  //-------------------------------------------------------------------------
700  // プッシュ関数
701  template< typename Type >
702  bool CArray< Type >::Push( std::initializer_list< Type const > const& rcInitializer ) noexcept {
703  // 追加する
704  return Append( rcInitializer );
705  }
706 
707  //-------------------------------------------------------------------------
708  // ポップ関数
709  template< typename Type >
710  bool CArray< Type >::Pop( Type& rElement ) noexcept {
711  // 処理ブロック
712  bool result = false;
713  do {
714  // 配列要素数を取得する
715  if ( !Get( ( m_nCount - 1 ), rElement ) ) {
716  // 失敗!
717  break;
718  }
719  // 削除する
720  else if ( !Remove() ) {
721  // 失敗!
722  break;
723  }
724 
725  // 成功!
726  result = true;
727  } while ( false );
728 
729  // 実行結果を返す
730  return result;
731  }
732 
733  //-------------------------------------------------------------------------
734  // ポップフロント関数
735  template< typename Type >
736  bool CArray< Type >::PopFront( Type& rElement ) noexcept {
737  // 処理ブロック
738  bool result = false;
739  do {
740  // 配列要素数を取得する
741  if ( !Get( 0, rElement ) ) {
742  // 失敗!
743  break;
744  }
745  // 削除する
746  else if ( !Remove( 0 ) ) {
747  // 失敗!
748  break;
749  }
750 
751  // 成功!
752  result = true;
753  } while ( false );
754 
755  // 実行結果を返す
756  return result;
757  }
758 }
759 
760 #pragma managed( pop )
virtual bool CreateBuffer(int nSize) noexcept
バッファ作成関数
Definition: CArray.hpp:222
virtual bool Set(int nIndex, Type const &rElement) noexcept
設定関数
Definition: CArray.hpp:613
virtual ~CArray() noexcept
デストラクタ
Definition: CArray.hpp:96
virtual bool Remove() noexcept
削除関数
Definition: CArray.hpp:528
virtual bool Move(CArray &&rcInstance) noexcept
ムーブ関数
Definition: CArray.hpp:365
配列クラスヘッダファイル
virtual bool Append(CArray const &rcInstance) noexcept
追加関数
Definition: CArray.hpp:393
virtual void Clear() noexcept
クリア関数
Definition: CArray.hpp:209
CArray() noexcept
コンストラクタ
Definition: CArray.hpp:31
配列クラス
Definition: CArray.h:33
共通ライブラリ名前空間
Definition: CArray.h:23
virtual bool Push(Type const &rElement) noexcept
プッシュ関数
Definition: CArray.hpp:686
virtual int Find(Type const &rElement) const noexcept
検索関数
Definition: CArray.hpp:637
virtual bool Pop(Type &rElement) noexcept
ポップ関数
Definition: CArray.hpp:710
virtual bool Compare(Type const &rElement1, Type const &rElement2) const noexcept
比較関数
Definition: CArray.hpp:659
virtual CArray & operator+=(CArray const &rcInstance) noexcept
加算代入演算子オーバーロード関数
Definition: CArray.hpp:150
virtual bool Get(int nIndex, Type &rElement) const noexcept
取得関数
Definition: CArray.hpp:589
virtual Type & operator[](int nIndex) noexcept
配列添字演算子オーバーロード関数
Definition: CArray.hpp:183
virtual bool Insert(int nIndex, CArray const &rcInstance) noexcept
挿入関数
Definition: CArray.hpp:425
virtual bool CompactBuffer() noexcept
バッファサイズコンパクト化関数
Definition: CArray.hpp:297
virtual bool Copy(CArray const &rcInstance) noexcept
コピー関数
Definition: CArray.hpp:321
virtual CArray & operator=(CArray const &rcInstance) noexcept
コピー代入演算子オーバーロード関数
Definition: CArray.hpp:106
virtual bool PopFront(Type &rElement) noexcept
ポップフロント関数
Definition: CArray.hpp:736
virtual bool UpdateBuffer(int nCount) noexcept
バッファサイズ更新関数
Definition: CArray.hpp:270