/// ****************************************************************************
/// @file   
/// @author Dr.Neeton
/// @date   200X/X/X - 2015/01/16
/// 
/// @brief  数値文字列変換用簡易クラス。
/// 
/// ****************************************************************************

#pragma once

#include "CPL_Core_String.h"


namespace CPL {
namespace Core {

  
// _____________________________________________________________________________
/// @brief 数値文字列フォーマット用クラス
///
// *****************************************************************************
template<class T_STR>
class NumString_X_
  : public String_X_<T_STR>
{
public:
  template<class T>
  NumString_X_
  ( T const& value
  , bool     f_plus    = false
  , int      width     = 0
  , bool     f_zero    = false
  , int      precision = 6 )
  {
    T_STR tmp[ 256 ] = { 0 };
    T_STR*  pset = tmp;
    T value_ = Abs( value );
    bool is_view_plus  = f_plus && (value > 0);
    bool is_view_minus = f_plus || (value < 0);
    width -= (is_view_minus || is_view_plus);

    if( f_zero ) // 0で埋める場合、すぐに符号表示処理をする。
    {
      // 符号
      if( is_view_plus  ) *pset++ = SwS('+');
      if( is_view_minus ) *pset++ = SwS('-');
    }

    // zero & num
    int num = 0;
    T_STR ct[ 16 ];

    do {
      ct[ num++ ] = int(value_) % 10 + SwS('0');
      value_ /= 10;
    } while( value_ >= 1 );

    while( num < width )
    {
      *pset = f_zero ? SwS('0') : SwS(' ');
      ++pset;
      --width;
    }
    if( !f_zero ) // ０で埋めない場合はここで符号表示チェック。
    {
      if( is_view_plus  ) *pset++ = SwS('+');
      if( is_view_minus ) *pset++ = SwS('-');
    }
    while( 0 < num-- )
    {
      *pset = ct[ num ];
      ++pset;
    }
    // precision
    if( Traits::IsFloat<T>::value )
    {
      T fv = Abs(value - long(value)); // 少数部分抜き出し
      if( precision > 0 )
      {
        *pset = SwS('.');
        ++pset;
      }
      while( precision > 0 )
      {
        fv *= 10;
        *pset = int(fv) + SwS('0');
        ++pset;
        fv -= long(fv);
        --precision;
      }
    }

    *pset = 0;
    *((String_X_<T_STR>*)this) = tmp;
  }
};




using NumString  = NumString_X_<str_type>;
using NumStringA = NumString_X_<char>;
using NumStringW = NumString_X_<wchar_t>;


} // namespace Core
} // namespace CPL
