/// ****************************************************************************
/// @file   
/// @author Dr.Neeton
/// @date   2002/X/X - 2013/09/13
/// 
/// @brief  固定長配列
/// 
/// ****************************************************************************

#pragma once

#include <new.h>

#include "../../Base/CPL_Core_Basic.h"
#include "../../Pointer/CPL_Core_Iterator.h"
#include "../../Memory/CPL_Core_Allocator.h"


namespace CPL {
namespace Core {
namespace Array {


/// @cond
namespace zzz_ {
// _____________________________________________________________________________
/// @brief 基本配列管理クラス
///
/// ※ このクラスは単体では使えません。
///
// *****************************************************************************
template<class T_Type>
class BaseArray
  : public Core::BaseObject
{
public:
  using type_target      = T_Type;
  using type_target_ptr  = type_target*;
  using type_target_cptr = type_target const*;
  using type_target_ref  = type_target&;
  using type_target_cref = type_target const&;
protected:
  type_target_ptr m_ptr;
  size_t          m_num;

  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // 領域確保
  type_target_ptr zzf_New_( size_t in_num )
  {
    return
      reinterpret_cast<type_target_ptr>(
        Memory::Allocator( sizeof(T_Type) * in_num, Memory::AllocCS(), "", 0 ));
  }
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // 領域開放
  void zzf_Del_( type_target_ptr& io_ptr )
  {
    if( io_ptr )
    {
      Memory::Deleter( (void*)(io_ptr), Memory::AllocCS() );
      io_ptr = nullptr;
    }
  }

  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // コンストラクタ呼び出し
  void zzf_Constructor_( type_target_ptr io_ptr )
  {
    new( io_ptr ) T_Type;
  }
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // コンストラクタ呼び出し（volatile仕様）
  void zzf_Constructor_( T_Type volatile* volatile io_ptr ) volatile
  {
    new( io_ptr ) T_Type;
  }
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // コピーコンストラクタ呼び出し
  void zzf_Constructor_( type_target_ptr io_ptr, type_target_cref in_init_data )
  {
    new( io_ptr ) T_Type( in_init_data );
  }
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // コピーコンストラクタ呼び出し（volatile仕様）
  void zzf_Constructor_(
    T_Type volatile* volatile io_ptr,
    T_Type cpl_cv&            in_init_data ) volatile
  {
    new( io_ptr ) T_Type( in_init_data );
  }
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // 指定された範囲のコンストラクタ呼び出し
  void zzf_ConstructorBlock_(
    type_target_ptr  in_ptr_start,
    type_target_cptr in_ptr_last )
  {
    while( in_ptr_start <= in_ptr_last )
    {
      zzf_Constructor_( in_ptr_start++ );
    }
  }
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // 指定された範囲のコンストラクタ呼び出し（volatile仕様）
  void zzf_ConstructorBlock_(
    T_Type volatile* volatile in_ptr_start,
    T_Type cpl_cv*   volatile in_ptr_last ) volatile
  {
    while( in_ptr_start <= in_ptr_last )
    {
      zzf_Constructor_( in_ptr_start++ );
    }
  }
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // 指定された範囲のコピーコンストラクタ呼び出し
  void zzf_ConstructorBlock_(
    type_target_ptr  in_ptr_start,
    type_target_cptr in_ptr_last,
    type_target_cref in_init_data )
  {
    while( in_ptr_start <= in_ptr_last )
    {
      zzf_Constructor_( in_ptr_start++, in_init_data );
    }
  }
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // 指定された範囲のコピーコンストラクタ呼び出し（volatile仕様）
  void zzf_ConstructorBlock_(
    T_Type volatile* volatile in_ptr_start,
    T_Type cpl_cv*   volatile in_ptr_last,
    T_Type cpl_cv&            in_init_data ) volatile
  {
    while( in_ptr_start <= in_ptr_last )
    {
      zzf_Constructor_( in_ptr_start++, in_init_data );
    }
  }
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // 指定された範囲のコピーコンストラクタ呼び出し（コピー用リストバージョン）
  void zzf_ConstructorBlock_(
    type_target_ptr  in_ptr_start,
    type_target_cptr in_ptr_last,
    type_target_cptr in_init_data_table )
  {
    while( in_ptr_start <= in_ptr_last )
    {
      zzf_Constructor_( in_ptr_start, *in_init_data_table );
      ++in_ptr_start;
      ++in_init_data_table;
    }
  }
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // 指定された範囲のコピーコンストラクタ呼び出し（コピー用リストバージョン＋volatile仕様）
  void zzf_ConstructorBlock_(
    T_Type volatile* volatile in_ptr_start,
    T_Type cpl_cv*   volatile in_ptr_last,
    T_Type cpl_cv*   volatile in_init_data_table ) volatile
  {
    while( in_ptr_start <= in_ptr_last )
    {
      zzf_Constructor_( in_ptr_start, *in_init_data_table );
      ++in_ptr_start;
      ++in_init_data_table;
    }
  }

  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // デストラクタ呼び出し
  template<class T_Class>
  void zzf_Destructor_( T_Class* io_ptr )
  {
    io_ptr->~T_Class();
  }
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // デストラクタ呼び出し（volatile仕様）
  template<class T_Class>
  void zzf_Destructor_( T_Class volatile* volatile io_ptr ) volatile
  {
    io_ptr->~T_Class();
  }

  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // 指定された範囲のデストラクタ呼び出し
  void zzf_DestructorBlock_(
    type_target_ptr in_ptr_start,
    type_target_ptr in_ptr_last )
  {
    while( in_ptr_start <= in_ptr_last )
    {
      zzf_Destructor_( in_ptr_start++ );
    }
  }
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // 指定された範囲のデストラクタ呼び出し（volatile仕様）
  void zzf_DestructorBlock_(
    T_Type volatile* volatile in_ptr_start,
    T_Type cpl_cv*   volatile in_ptr_last ) volatile
  {
    while( in_ptr_start <= in_ptr_last )
    {
      zzf_Destructor_( in_ptr_start++ );
    }
  }

  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // in_ptr から out_ptr へ num個 コピーする
  void zzf_CopyBlock_(
    type_target_ptr  out_ptr,
    type_target_cptr in_ptr,
    size_t           in_num )
  {
//    memcpy( out_ptr, in_ptr, sizeof(T_Type)*in_num ); // bitコピーは不可
    for( size_t i = 0; i < in_num; ++i )
    {
      *out_ptr = *in_ptr;
      ++out_ptr;
      ++in_ptr;
    }
  }
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // in_ptr から out_ptr へ num個 コピーする（volatile仕様）
  void zzf_CopyBlock_(
    T_Type volatile* volatile out_ptr,
    T_Type cpl_cv*   volatile in_ptr,
    size_t                    in_num ) volatile
  {
//    memcpy( out_ptr, in_ptr, sizeof(T_Type)*in_num ); // bitコピーは不可
    for( size_t i = 0; i < in_num; ++i )
    {
      *out_ptr = *in_ptr;
      ++out_ptr;
      ++in_ptr;
    }
  }
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // 部分移動。
  // ※ 移動元に新規要素が入るのが前提。
  //    移動先は領域のみ確保してある状態が前提。
  //    つまり、元のオブジェクトは不変である。
  template<class T_ValueType>
  void zzf_MoveBlock_(
    type_target_ptr in_ptr_start,
    type_target_ptr in_ptr_last,
    T_ValueType     in_offset )
  {
    if( in_ptr_start > in_ptr_last )
      return;

    if( in_offset > 0 ) // 右移動
    {
      type_target_ptr pEnd = GetEnd();
      if( in_ptr_start + in_offset > pEnd ){ return; }
      if( in_ptr_last  + in_offset > pEnd ){ in_ptr_last = pEnd - in_offset; }

      type_target_ptr pDest  = in_ptr_last + in_offset;
      type_target_ptr pStart = in_ptr_last;
      type_target_ptr pLast  = in_ptr_start;
      while( pStart >= pLast )
      {
        *pDest = *pStart;
        --pDest;
        --pStart;
      }
    }
    else
    if( in_offset < 0 ) // 左移動
    {
      type_target_ptr pTop = GetTop();
      if( in_ptr_last  + in_offset < pTop ){ return; }
      if( in_ptr_start + in_offset < pTop ){ in_ptr_start = pTop - in_offset; }

      type_target_ptr pDest  = in_ptr_start + in_offset;
      type_target_ptr pStart = in_ptr_start;
      type_target_ptr pLast   = in_ptr_last;
      while( pStart <= pLast )
      {
        *pDest = *pStart;
        ++pDest;
        ++pStart;
      }
    }
  }
  
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // 部分移動（volatile仕様）
  // ※ 移動元に新規要素が入るのが前提。
  //    移動先は領域のみ確保してある状態が前提。
  //    つまり、元のオブジェクトは不変である。
  template<class T_ValueType>
  void zzf_MoveBlock_(
    T_Type volatile* volatile in_ptr_start,
    T_Type cpl_cv*   volatile in_ptr_last,
    T_ValueType               in_offset ) volatile
  {
    if( in_ptr_start > in_ptr_last )
      return;

    if( in_offset > 0 ) // 右移動
    {
      type_target_ptr pEnd = GetEnd();
      if( in_ptr_start + in_offset > pEnd ){ return; }
      if( in_ptr_last  + in_offset > pEnd ){ in_ptr_last = pEnd - in_offset; }

      type_target_ptr pDest  = in_ptr_last + in_offset;
      type_target_ptr pStart = in_ptr_last;
      type_target_ptr pLast  = in_ptr_start;
      while( pStart >= pLast )
      {
        *pDest = *pStart;
        --pDest;
        --pStart;
      }
    }
    else
    if( in_offset < 0 ) // 左移動
    {
      type_target_ptr pTop = GetTop();
      if( in_ptr_last  + in_offset < pTop ){ return; }
      if( in_ptr_start + in_offset < pTop ){ in_ptr_start = pTop - in_offset; }

      type_target_ptr pDest  = in_ptr_start + in_offset;
      type_target_ptr pStart = in_ptr_start;
      type_target_ptr pLast   = in_ptr_last;
      while( pStart <= pLast )
      {
        *pDest = *pStart;
        ++pDest;
        ++pStart;
      }
    }
  }
  

  // _____________________________________________________________________________
  /// @brief イテレータ用加算クラス
  ///
  // *****************************************************************************
  struct IIAdd {
    template<class T_Iterator, class T_Value>
    static T_Iterator&
      Call( T_Iterator* io_ptr_itr, T_Value in_val )
    {
      io_ptr_itr->zzf_setTargetPtr_( io_ptr_itr->zzf_getTargetPtr_() + in_val );
      return *io_ptr_itr;
    }

    template<class T_Iterator>
    static T_Iterator&
      Call( T_Iterator* io_ptr_itr )
    {
      io_ptr_itr->zzf_setTargetPtr_( io_ptr_itr->zzf_getTargetPtr_() + 1 );
      return *io_ptr_itr;
    }
  };
  // _____________________________________________________________________________
  /// @brief イテレータ用減算クラス
  ///
  // *****************************************************************************
  struct IISub {
    template<class T_Iterator, class T_Value>
    static T_Iterator&
      Call( T_Iterator* io_ptr_itr, T_Value in_val )
    {
      io_ptr_itr->zzf_setTargetPtr_( io_ptr_itr->zzf_getTargetPtr_() - in_val );
      return *io_ptr_itr;
    }

    template<class T_Iterator>
    static T_Iterator&
      Call( T_Iterator* io_ptr_itr )
    {
      io_ptr_itr->zzf_setTargetPtr_( io_ptr_itr->zzf_getTargetPtr_() - 1 );
      return *io_ptr_itr;
    }
  };

public:
  BaseArray() : m_ptr(nullptr) {}

  // _____________________________________________________________________________
  /// @brief 配列参照。
  ///
  /// @param[in] in_idx : 参照する要素のインデックス。
  ///
  /// @return 要素の参照を返す。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  type_target_ref operator []( size_t in_idx )
  {
    CPL_WAIT( in_idx >= m_num );
    return m_ptr[ in_idx ];
  }
  // _____________________________________________________________________________
  /// @brief 配列参照。※ const type
  ///
  /// @param[in] in_idx : 参照する要素のインデックス。
  ///
  /// @return 要素の参照を返す。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  type_target_cref operator []( size_t in_idx ) const
  {
    CPL_WAIT( in_idx >= m_num );
    return m_ptr[ in_idx ];
  }
  
  type_target_ptr  GetTop()       { return m_num > 0 ? m_ptr : nullptr;       }   ///< 先頭の要素を取得
  type_target_cptr GetTop() const { return m_num > 0 ? m_ptr : nullptr;       }   ///< 先頭の要素を取得 ※ const type
  type_target_ptr  GetEnd()       { return m_num > 0 ? m_ptr+m_num-1 : nullptr; } ///< 最後の要素を取得
  type_target_cptr GetEnd() const { return m_num > 0 ? m_ptr+m_num-1 : nullptr; } ///< 最後の要素を取得 ※ const type

  // _____________________________________________________________________________
  /// @brief 予約個数を取得。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  size_t   GetNum() const { return m_num; }

  // _____________________________________________________________________________
  /// @brief 予約個数を取得。（STL互換用）
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  size_t   size() const { return m_num; }

  // _____________________________________________________________________________
  /// @brief 予約バイトサイズを取得。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  size_t   GetSize() const { return m_num * sizeof(T_Type); }
  
  // _____________________________________________________________________________
  /// @brief
  /// 指定したポインタのインデックスを返す。\n
  /// ※ 該当しない場合は-1(全ビットON)を返す。
  ///
  /// @param[in] in_ptr_data : 検索ポインタ。
  ///
  /// @return 該当した要素のインデックス。該当しない場合、-1(全ビットON)を返す。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  size_t   GetIndex( type_target_cptr in_ptr_data ) const
  {
    if( GetTop() <= in_ptr_data  &&  in_ptr_data <= GetEnd() )
    {
      return in_ptr_data - m_ptr;
    }
    return -1;
  }

  // _____________________________________________________________________________
  /// @brief 該当するデータを検索してインデックスを取得。該当なしで-1を返す。
  ///
  /// @param[in] in_key : 検索データ。
  ///
  /// @return 該当した要素のインデックス。該当しない場合、-1(全ビットON)を返す。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  template<class T_Key>
  size_t   Find( const T_Key& in_key ) const
  {
    type_target_cptr       ptr_search = GetTop();
    type_target_cptr const ptr_end    = GetEnd();
    if( !ptr_search )
    {
      return -1;
    }

    for(; ptr_search <= ptr_end; ptr_search++ )
    {
      if( *ptr_search == in_key )
      {
        return ptr_search - GetTop();
      }
    }

    return -1;
  }


  // _____________________________________________________________________________
  /// @brief イテレータ
  class iterator
    : public Itr::random_access_iterator_
      < type_target_ptr, iterator, 0, IIAdd, IISub>
  {
    using type_base =
      Itr::random_access_iterator_
      < type_target_ptr, iterator, 0, IIAdd, IISub>;
  public:
    using type_base::type_base;
  };
  
  // _____________________________________________________________________________
  /// @brief const イテレータ
  class const_iterator
    : public Itr::random_access_iterator_
      < type_target_cptr, const_iterator, 0, IIAdd, IISub>
  {
    using type_base =
      Itr::random_access_iterator_
      < type_target_cptr, const_iterator, 0, IIAdd, IISub>;
  public:
    using type_base::type_base;
  };
  
  // _____________________________________________________________________________
  /// @brief 逆イテレータ
  class reverse_iterator
    : public Itr::random_access_iterator_
      < type_target_ptr, reverse_iterator, -1, IISub, IIAdd>
  {
    using type_base =
      Itr::random_access_iterator_
      < type_target_ptr, reverse_iterator, -1, IISub, IIAdd>;
  public:
    using type_base::type_base;
  };
  
  // _____________________________________________________________________________
  /// @brief const 逆イテレータ
  ///
  // *****************************************************************************
  class const_reverse_iterator
    : public Itr::random_access_iterator_
      < type_target_cptr, const_reverse_iterator, -1, IISub, IIAdd>
  {
    using type_base =
      Itr::random_access_iterator_
      < type_target_cptr, const_reverse_iterator, -1, IISub, IIAdd>;
  public:
    using type_base::type_base;
  };


  iterator               begin()        { return iterator              (m_ptr + 0); }
  const_iterator         begin() const  { return const_iterator        (m_ptr + 0); }
  iterator               end()          { return iterator              (m_ptr + m_num, true); }
  const_iterator         end()   const  { return const_iterator        (m_ptr + m_num, true); }
  reverse_iterator       rbegin()       { return reverse_iterator      (m_ptr + m_num, true); }
  const_reverse_iterator rbegin() const { return const_reverse_iterator(m_ptr + m_num, true); }
  reverse_iterator       rend()         { return reverse_iterator      (m_ptr + 0); }
  const_reverse_iterator rend() const   { return const_reverse_iterator(m_ptr + 0); }
};


} // namespace zzz_
/// @endcond






// _____________________________________________________________________________
/// @brief 固定配列クラス
///
// *****************************************************************************
template<class T_Type>
class Constant
  : public zzz_::BaseArray<T_Type>
{
  using td_base = zzz_::BaseArray<T_Type>;
  using td_self = Constant<T_Type>;

protected:
  using type_target_cref = typename td_base::type_target_cref;

  Constant() // 継承用
  {
    this->m_num  = 0;
  }

public:
  // _____________________________________________________________________________
  /// @brief 代入。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  td_self& operator = ( const td_self& in_array )
  {
    // 自己代入判定
    if( this == &in_array )
    {
      return *this;
    }

    // 新しく確保
  //  sp::Linked<T_Type> new_ptr = zzf_New_( in_array.GetNum() );
    T_Type* new_ptr = zzf_New_( in_array.GetNum() );

    zzf_ConstructorBlock_( new_ptr, &new_ptr[ in_array.GetNum()-1 ] ); // コンストラクタ呼び出し
    zzf_CopyBlock_( new_ptr, this->m_ptr, this->m_num ); // コピー
    Release(); // 開放

    this->m_ptr = new_ptr; // 新しいポインタを設定
    this->m_num = in_array.GetNum();

    return *this;
  }

  // _____________________________________________________________________________
  /// @brief 全データを削除し、領域を開放する。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  void Release()
  {
    if( this->m_ptr )
    {
      if( this->m_num > 0 )
      {
        this->zzf_DestructorBlock_( this->GetTop(), this->GetEnd() );
      }
      this->zzf_Del_( this->m_ptr );
      this->m_num = 0;
    }
  }

  // _____________________________________________________________________________
  /// @brief サイズ指定付きコンストラクタ。
  /// 
  /// @param[in] in_capacity : 配列の要素数を指定。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  Constant( size_t in_capacity )
  {
    this->m_num = in_capacity;
    this->m_ptr = this->zzf_New_( in_capacity );
    this->zzf_ConstructorBlock_( this->GetTop(), this->GetEnd() );
  }

  // _____________________________________________________________________________
  /// @brief サイズ指定＆初期化付きコンストラクタ。
  ///
  /// @param[in] in_capacity : 配列の要素数を指定。
  /// @param[in] in_ref      : 設定するデータ。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  Constant( size_t in_capacity, type_target_cref in_ref )
  {
    this->m_num = in_capacity;
    this->m_ptr = this->zzf_New_( in_capacity );
    this->zzf_ConstructorBlock_( this->GetTop(), this->GetEnd(), in_ref );
  }

  // _____________________________________________________________________________
  /// @brief デストラクタ。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  ~Constant()
  {
    Release();
  }
};



// 基本型配列定義
typedef Constant<char>   C_Char;
typedef Constant<short>  C_Short;
typedef Constant<int>    C_Int;
typedef Constant<float>  C_Float;
typedef Constant<double> C_Double;

typedef Constant<S8>     C_S8;
typedef Constant<U8>     C_U8;
typedef Constant<S16>    C_S16;
typedef Constant<U16>    C_U16;
typedef Constant<S32>    C_S32;
typedef Constant<U32>    C_U32;
typedef Constant<S64>    C_S64;
typedef Constant<U64>    C_U64;


} // namespace Array
} // namespace Core
} // namespace CPL
