/// ****************************************************************************
/// @file   
/// @author Dr.Neeton
/// @date   200X/X/X - 2014/01/24
/// 
/// @brief  DirectX シェーダー用キーワード関連
/// 
/// ****************************************************************************

#pragma once

#include "CPL_DX_Shader_Strings.h"

namespace CPL {
namespace DX {
namespace Shader {


// 静的パラメータ簡易宣言用マクロ
#define CPL_DX_DECL_STATIC_VAL_CSS1(name)  CPL_DECL_TYPENUM1 (static css32,name)
#define CPL_DX_DECL_STATIC_VAL_CSS2(name)  CPL_DECL_TYPENUM2 (static css32,name)
#define CPL_DX_DECL_STATIC_VAL_CSS3(name)  CPL_DECL_TYPENUM3 (static css32,name)
#define CPL_DX_DECL_STATIC_VAL_CSS4(name)  CPL_DECL_TYPENUM4 (static css32,name)
#define CPL_DX_DECL_STATIC_VAL_CSS1_(name) CPL_DECL_TYPENUM1E(static css32,name,_)
#define CPL_DX_DECL_STATIC_VAL_CSS2_(name) CPL_DECL_TYPENUM2E(static css32,name,_)
#define CPL_DX_DECL_STATIC_VAL_CSS3_(name) CPL_DECL_TYPENUM3E(static css32,name,_)
#define CPL_DX_DECL_STATIC_VAL_CSS4_(name) CPL_DECL_TYPENUM4E(static css32,name,_)

// 静的css定義簡易化用マクロ
#define CPL_DX_DEF_STATIC_VAL_CSS_MTX(type)\
  CPL_DECL_TYPENUM4E(static css32,type,x1);\
  CPL_DECL_TYPENUM4E(static css32,type,x2);\
  CPL_DECL_TYPENUM4E(static css32,type,x3);\
  CPL_DECL_TYPENUM4E(static css32,type,x4)
#define CPL_DX_DEF_STATIC_VAL_CSS_MTX_(type)\
  CPL_DECL_TYPENUM4E(static css32,type,x1_);\
  CPL_DECL_TYPENUM4E(static css32,type,x2_);\
  CPL_DECL_TYPENUM4E(static css32,type,x3_);\
  CPL_DECL_TYPENUM4E(static css32,type,x4_)

//// キーワード用の型定義の簡略化用マクロ（スカラー＆ベクトル用）
//#define CPL_DX_HLSL_KEYWORD_TYPES_for_SCALAR_and_VECTOR(type)\
//  struct type##_{}; struct type##1_{}; struct type##2_{}; struct type##3_{}; struct type##4_{}
//  
//// キーワード用の型定義の簡略化用マクロ（マトリクス用）
//#define CPL_DX_HLSL_KEYWORD_TYPES_for_matrix(type)\
//  struct type##1x1_{}; struct type##1x2_{}; struct type##1x3_{}; struct type##1x4_{};\
//  struct type##2x1_{}; struct type##2x2_{}; struct type##2x3_{}; struct type##2x4_{};\
//  struct type##3x1_{}; struct type##3x2_{}; struct type##3x3_{}; struct type##3x4_{};\
//  struct type##4x1_{}; struct type##4x2_{}; struct type##4x3_{}; struct type##4x4_{}
//// キーワード用の型定義の簡略化用マクロ（マトリクス用）
//#define CPL_DX_HLSL_KEYWORD_TYPES_for_MATRIX(type)\
//  struct type##1x1{}; struct type##1x2{}; struct type##1x3{}; struct type##1x4{};\
//  struct type##2x1{}; struct type##2x2{}; struct type##2x3{}; struct type##2x4{};\
//  struct type##3x1{}; struct type##3x2{}; struct type##3x3{}; struct type##3x4{};\
//  struct type##4x1{}; struct type##4x2{}; struct type##4x3{}; struct type##4x4{}


// _____________________________________________________________________________
/// @brief シェーダー用キーワード等。
///
// *****************************************************************************
class CodeKeywords
  : public CodeStrings
{
protected:

  //static char_cptr      _toTypeStrings( int in_type );
  //static char_cptr      _toUsageStrings( int in_usage, int in_usage_index );
  //static int            _GetElementTableNum( DX_IN_ELEMENT_DESC const* in_ptr_element );
  //static _ELEMENT_USAGE _GetElementUsageFlag( DX_IN_ELEMENT_DESC const* in_ptr_element );
  
  // reserved words
  static css32
    auto_,
    case_, catch_, char_, class_, const_cast_,
    default_, delete_, dynamic_cast_,
    enum_, explicit_,
    friend_,
    goto_,
    long_,
    mutable_,
    new_,
    operator_,
    private_, protected_, public_,
    reinterpret_cast_,
    short_, signed_, sizeof_, static_cast_,
    template_, this_, throw_, try_, typename_,
    union_, unsigned_, using_,
    virtual_;

  // keywords
  static css32 if_, If;    // if
  static css32 else_, Else; // else
  static css32 for_, while_, do_; // for / while / do
  static css32 For, While, Do;    // for / while / do
  static css32 in_, out_, inout_; // in / out / inout
  static css32 In, Out, Inout;    // in / out / inout
  static css32 void_, Void;
  static css32 bool_, Bool;
  static css32 int_, Int;
  CPL_DX_DECL_STATIC_VAL_CSS4_( int );
  CPL_DX_DECL_STATIC_VAL_CSS4( Int );
  static css32 uint_, Uint;
  CPL_DX_DECL_STATIC_VAL_CSS4_( uint );
  CPL_DX_DECL_STATIC_VAL_CSS4 ( Uint );
  static css32 float_, Float;
  CPL_DX_DECL_STATIC_VAL_CSS4_( float );
  CPL_DX_DECL_STATIC_VAL_CSS4 ( Float );
  static css32 double_, Double;
  CPL_DX_DECL_STATIC_VAL_CSS4_( double );
  CPL_DX_DECL_STATIC_VAL_CSS4 ( Double );
  static css32 texture_, texture1_;
  static css32 cbuffer_, CBuffer;
  static css32 tbuffer_, TBuffer;
  static css32 break_, Break;
  static css32 buffer_, Buffer;
  //static css32 class_, Class;
  static css32 compile_, Compile;
  static css32 const_, Const;
  static css32 continue_, Continue;
  static css32 depthstencilstate_, DepthStencilState;
  static css32 depthstencilview_, DepthStencilView;
  static css32 discard_, Discard;
  static css32 extern_, Extern;
  static css32 false_, False;
  static css32 true_, True;
  static css32 geometryshader_, GeometryShader;
  static css32 inline_, Inline;
  static css32 interface_, Interface_;
  static css32 namespace_, Namespace;
  static css32 nointerpolation_, Nointerpolation;
  static css32 pass_, Pass;
  static css32 pixelshader_, PixelShader;
  static css32 precise_, Precise;
  static css32 rasterizerstate_, RasterizerState;
  static css32 rendertargetview_, RenderTargetView;
  static css32 return_, Return;
  static css32 register_, Register;
  static css32 sampler_, Sampler;
  CPL_DECL_TYPENUM3E( static css32, sampler, d_);
  CPL_DECL_TYPENUM3E( static css32, Sampler, D);
  static css32 samplercube_, SamplerCUBE;
  static css32 sampler_state_, SamplerState;
  static css32 samplercomparisonstate_, SamplerComparisonState;
  static css32 shared_, Shared;
  static css32 stateblock_, Stateblock;
  static css32 stateblock_state_, Stateblock_state;
  static css32 static_, Static;
  static css32 string_, String;
  static css32 struct_, Struct;
  static css32 switch_, Switch;
  static css32 technique_, Technique;
  static css32 technique10_, Technique10;
  static css32 texture1d_, Texture1D;
  static css32 texture1darray_, Texture1DArray;
  static css32 texture2d_, Texture2D;
  static css32 texture2darray_, Texture2DArray;
  static css32 texture2dms_, Texture2DMS;
  static css32 texture2dmsarray_, Texture2DMSArray;
  static css32 texture3d_, Texture3D;
  static css32 texturecube_, TextureCube;
  static css32 texturecubearray_, TextureCubeArray;
  static css32 typedef_, Typedef;
  static css32 uniform_, Uniform;
  static css32 vector_, Vector;
  static css32 vertexshader_, VertexShader;
  static css32 volatile_, Volatile;
  CPL_DX_DEF_STATIC_VAL_CSS_MTX_( int );
  CPL_DX_DEF_STATIC_VAL_CSS_MTX( Int );
  CPL_DX_DEF_STATIC_VAL_CSS_MTX_( uint );
  CPL_DX_DEF_STATIC_VAL_CSS_MTX( Uint );
  CPL_DX_DEF_STATIC_VAL_CSS_MTX_( float );
  CPL_DX_DEF_STATIC_VAL_CSS_MTX( Float );
  CPL_DX_DEF_STATIC_VAL_CSS_MTX_( double );
  CPL_DX_DEF_STATIC_VAL_CSS_MTX( Double );


  // other
  static css32 Yn;    // \nの代わり
public:
  // variable name
  //static css16 vn_g_Texture;       // 配列にできないみたいなので、g_Texture0,g_Texture1...の形式をとる
  //static css16 vn_g_Sampler;       // 配列
  //static css16 vn_g_LightPos;      // 配列
  //static css16 vn_g_LightNormal;   // 配列
  //static css16 vn_g_LightAmbient;  
  //static css16 vn_g_LightDiffuse;  // 配列
  //static css16 vn_g_LightPower;    // 配列
  //static css16 vn_g_LightTheta;    // 配列
  //static css16 vn_g_LightPhi;      // 配列
  //static css16 vn_g_LightType;     // 配列
  //static css16 vn_g_EyePos;
  //static css16 vn_g_LookPos;
  //static css16 vn_g_MtrlColor;
  //static css16 vn_g_MtrlDiffuse;
  //static css16 vn_g_MtrlSpecular;
  //static css16 vn_g_MtrlEmissive;
  //static css16 vn_g_ViewProjMtx;
  //static css16 vn_g_MtxProj;
  //static css16 vn_g_MtxView;
  //static css16 vn_g_MtxWorld;

  //static css16 vn_l_Matrix;
  //static css16 vn_l_VtxPos;
  //static css16 vn_l_VtxNormal;
  //static css16 vn_l_Color;

  //static css16 vn_in_VtxPos;
  //static css16 vn_in_VtxPosT;
  //static css16 vn_in_VtxNormal;
  //static css16 vn_in_VtxColor;
  //static css16 vn_in_VtxBWeight;
  //static css16 vn_in_VtxBIndex;
  //static css16 vn_in_VtxPSize;
  //static css16 vn_in_VtxTexCoord;
  //static css16 vn_in_VtxTangent;
  //static css16 vn_in_VtxBiNormal;
  //static css16 vn_in_VtxTessFactor;
  //static css16 vn_in_Mtx;
  //static css16 vn_in_BW0;
  //static css16 vn_in_BIdx0;
  //static css16 vn_in_BIdx1;
  //static css16 vn_in_Color;
  //static css16 vn_in_TexCoord;
  //static css16 vn_in_VPos;
  //static css16 vn_in_VFace;
  //static css16 vn_in_AmbientColor;
  //static css16 vn_in_LightPos;
  //static css16 vn_in_LightNormal;
  //static css16 vn_in_LightDiffuse;
  //static css16 vn_in_LightPower;
  //static css16 vn_in_LightTheta;
  //static css16 vn_in_LightPhi;

  //static css16 vn_out_Color;
  //static css16 vn_out_ScPos;
  //static css16 vn_out_Mtx;
  //static css16 vn_out_VtxColor;
  //static css16 vn_out_PSize;
  //static css16 vn_out_Fog;
  //static css16 vn_out_TexCoord;
  //static css16 vn_out_Depth;

  //static css16 vn_io_VtxPos;
  //static css16 vn_io_VtxNormal;
  //static css16 vn_io_Mtx;
  //static css16 vn_io_Color;

  // semantics
  static css32 POSITION;
  static css32 POSITIONT;
  static css32 BLENDWEIGHT;
  static css32 BLENDINDICES;
  static css32 NORMAL;
  static css32 PSIZE;
  static css32 COLOR;
  static css32 TEXCOORD;
  static css32 TANGENT;
  static css32 BINORMAL;
  static css32 TESSFACTOR;
  static css32 FOG;
  static css32 VPOS;
  static css32 VFACE;
  static css32 DEPTH;
  static css32 SV_ClipDistance;           // [n]　クリップ距離データ	ラスタライザー	float
  static css32 SV_CullDistance;           // [n]　カリング距離データ	ラスタライザー	float
  static css32 SV_Coverage;               //	出力カバレッジ マスク	ラスタライザー	bool
  static css32 SV_Depth;                  //	深度バッファー データ	ラスタライザー	float
  static css32 SV_IsFrontFace;            //	見えているプリミティブ	ラスタライザー	bool
  static css32 SV_Position;               //	均質空間内の頂点位置	ラスタライザー	float4
  static css32 SV_RenderTargetArrayIndex; //	レンダー ターゲットの配列インデックス	ラスタライザー	uint
  static css32 SV_SampleIndex;            //	サンプル頻度インデックス データ	ピクセル シェーダー	uint
  static css32 SV_Target;                 // [n] ここで、0 <= n <= 7	レンダー ターゲットの配列	ラスタライザー	float
  static css32 SV_ViewportArrayIndex;     //	ビューポート配列インデックス	ラスタライザー	uint
  static css32 SV_InstanceID;             //	インスタンスごとの識別子	頂点シェーダー	uint
  static css32 SV_PrimitiveID;            //	プリミティブごとの識別子	ジオメトリ シェーダー、ピクセル シェーダー	uint
  static css32 SV_VertexID;               //	頂点ごとの識別子	頂点シェーダー	uint


private:
  static ss zzf_function1_(
    char_cptr func_name,
    char_cptr a )
  {
    return ss(func_name), "(", a, ")";
  }
  static ss zzf_function2_(
    char_cptr func_name,
    char_cptr a,
    char_cptr b )
  {
    return ss(func_name), "(", a, ",", b, ")";
  }
  static ss zzf_function3_(
    char_cptr func_name,
    char_cptr a,
    char_cptr b,
    char_cptr c )
  {
    return ss(func_name), "(", a, ",", b, ",", c, ")";
  }
  static ss zzf_function4_(
    char_cptr func_name,
    char_cptr a,
    char_cptr b,
    char_cptr c,
    char_cptr d )
  {
    return ss(func_name), "(", a, ",", b, ",", c, ",", d, ")";
  }
protected:
  // 関数名オーバーロード
  static ss abs             ( char_cptr a )                                           { return zzf_function1_( "abs",              a               ); }
  static ss acos            ( char_cptr x )                                           { return zzf_function1_( "acos",             x               ); }
  static ss all             ( char_cptr x )                                           { return zzf_function1_( "all",              x               ); }
  static ss any             ( char_cptr x )                                           { return zzf_function1_( "any",              x               ); }
  static ss asin            ( char_cptr x )                                           { return zzf_function1_( "asin",             x               ); }
  static ss atan            ( char_cptr x )                                           { return zzf_function1_( "atan",             x               ); }
  static ss atan2           ( char_cptr y, char_cptr x )                              { return zzf_function2_( "atan2",            y, x            ); }
  static ss ceil            ( char_cptr x )                                           { return zzf_function1_( "ceil",             x               ); }
  static ss clamp           ( char_cptr x, char_cptr min, char_cptr max )             { return zzf_function3_( "clamp",            x, min, max     ); }
  static ss clip            ( char_cptr x )                                           { return zzf_function1_( "clip",             x               ); }
  static ss cos             ( char_cptr x )                                           { return zzf_function1_( "cos",              x               ); }
  static ss cosh            ( char_cptr x )                                           { return zzf_function1_( "cosh",             x               ); }
  static ss cross           ( char_cptr a, char_cptr b )                              { return zzf_function2_( "cross",            a, b            ); }
  static ss D3DCOLORtoUBYTE4( char_cptr x )                                           { return zzf_function1_( "D3DCOLORtoUBYTE4", x               ); }
  static ss ddx             ( char_cptr x )                                           { return zzf_function1_( "ddx",              x               ); }
  static ss ddy             ( char_cptr x )                                           { return zzf_function1_( "ddy",              x               ); }
  static ss degrees         ( char_cptr x )                                           { return zzf_function1_( "degrees",          x               ); }
  static ss determinant     ( char_cptr m )                                           { return zzf_function1_( "determinant",      m               ); }
  static ss distance        ( char_cptr a, char_cptr b )                              { return zzf_function2_( "distance",         a, b            ); }
  static ss dot             ( char_cptr a, char_cptr b )                              { return zzf_function2_( "dot",              a, b            ); }
  static ss exp             ( char_cptr x )                                           { return zzf_function1_( "exp",              x               ); }
  static ss exp2            ( char_cptr a )                                           { return zzf_function1_( "exp2",             a               ); }
  static ss faceforward     ( char_cptr n, char_cptr i, char_cptr ng )                { return zzf_function3_( "faceforward",      n, i, ng        ); }
  static ss floor           ( char_cptr x )                                           { return zzf_function1_( "floor",            x               ); }
  static ss fmod            ( char_cptr a, char_cptr b )                              { return zzf_function2_( "fmod",             a, b            ); }
  static ss frac            ( char_cptr x )                                           { return zzf_function1_( "frac",             x               ); }
  static ss frc             ( char_cptr a )                                           { return zzf_function1_( "frc",              a               ); }
  static ss frexp           ( char_cptr x, char_cptr exp )                            { return zzf_function2_( "frexp",            x, exp          ); }
  static ss fwidth          ( char_cptr x )                                           { return zzf_function1_( "fwidth",           x               ); }
  static ss isfinite        ( char_cptr x )                                           { return zzf_function1_( "isfinite",         x               ); }
  static ss isinf           ( char_cptr x )                                           { return zzf_function1_( "isinf",            x               ); }
  static ss isnan           ( char_cptr x )                                           { return zzf_function1_( "isnan",            x               ); }
  static ss ldexp           ( char_cptr x, char_cptr exp )                            { return zzf_function2_( "ldexp",            x, exp          ); }
  static ss len             ( char_cptr a )                                           { return zzf_function1_( "len",              a               ); }
  static ss length          ( char_cptr v )                                           { return zzf_function1_( "length",           v               ); }
  static ss lerp            ( char_cptr a, char_cptr b, char_cptr s )                 { return zzf_function3_( "lerp",             a, b, s         ); }
  static ss lit             ( char_cptr ndotl, char_cptr ndoth, char_cptr m )         { return zzf_function3_( "lit",              ndotl, ndoth, m ); }
  static ss log             ( char_cptr x )                                           { return zzf_function1_( "log",              x               ); }
  static ss log10           ( char_cptr x )                                           { return zzf_function1_( "log10",            x               ); }
  static ss log2            ( char_cptr x )                                           { return zzf_function1_( "log2",             x               ); }
  static ss max             ( char_cptr a, char_cptr b )                              { return zzf_function2_( "max",              a, b            ); }
  static ss min             ( char_cptr a, char_cptr b )                              { return zzf_function2_( "min",              a, b            ); }
  static ss modf            ( char_cptr x, char_cptr ip )                             { return zzf_function2_( "modf",             x, ip           ); }
  static ss mul             ( char_cptr a, char_cptr b )                              { return zzf_function2_( "mul",              a, b            ); }
  static ss noise           ( char_cptr x )                                           { return zzf_function1_( "noise",            x               ); }
  static ss normalize       ( char_cptr v )                                           { return zzf_function1_( "normalize",        v               ); }
  static ss pow             ( char_cptr x, char_cptr y )                              { return zzf_function2_( "pow",              x, y            ); }
  static ss radians         ( char_cptr x )                                           { return zzf_function1_( "radians",          x               ); }
  static ss reflect         ( char_cptr i, char_cptr n )                              { return zzf_function2_( "reflect",          i, n            ); }
  static ss refract         ( char_cptr i, char_cptr n, char_cptr eta )               { return zzf_function3_( "refract",          i, n, eta       ); }
  static ss round           ( char_cptr x )                                           { return zzf_function1_( "round",            x               ); }
  static ss rsqrt           ( char_cptr x )                                           { return zzf_function1_( "rsqrt",            x               ); }
  static ss saturate        ( char_cptr x )                                           { return zzf_function1_( "saturate",         x               ); }
  static ss sign            ( char_cptr x )                                           { return zzf_function1_( "sign",             x               ); }
  static ss sin             ( char_cptr x )                                           { return zzf_function1_( "sin",              x               ); }
  static ss sincos          ( char_cptr x, char_cptr s, char_cptr c )                 { return zzf_function3_( "sincos",           x, s, c         ); }
  static ss sinh            ( char_cptr x )                                           { return zzf_function1_( "sinh",             x               ); }
  static ss smoothstep      ( char_cptr min, char_cptr max, char_cptr x )             { return zzf_function3_( "smoothstep",       min, max, x     ); }
  static ss sqrt            ( char_cptr a )                                           { return zzf_function1_( "sqrt",             a               ); }
  static ss step            ( char_cptr a, char_cptr x )                              { return zzf_function2_( "step",             a, x            ); }
  static ss tan             ( char_cptr x )                                           { return zzf_function1_( "tan",              x               ); }
  static ss tanh            ( char_cptr x )                                           { return zzf_function1_( "tanh",             x               ); }
  static ss tex1D           ( char_cptr s, char_cptr t )                              { return zzf_function2_( "tex1D",            s, t            ); }
  static ss tex1D           ( char_cptr s, char_cptr t, char_cptr ddx, char_cptr ddy ){ return zzf_function4_( "tex1D",            s, t, ddx, ddy  ); }
  static ss tex1Dproj       ( char_cptr s, char_cptr t )                              { return zzf_function2_( "tex1Dproj",        s, t            ); }
  static ss tex1Dbias       ( char_cptr s, char_cptr t )                              { return zzf_function2_( "tex1Dbias",        s, t            ); }
  static ss tex2D           ( char_cptr s, char_cptr t )                              { return zzf_function2_( "tex2D",            s, t            ); }
  static ss tex2D           ( char_cptr s, char_cptr t, char_cptr ddx, char_cptr ddy ){ return zzf_function4_( "tex2D",            s, t, ddx, ddy  ); }
  static ss tex2Dproj       ( char_cptr s, char_cptr t )                              { return zzf_function2_( "tex2Dproj",        s, t            ); }
  static ss tex2Dbias       ( char_cptr s, char_cptr t )                              { return zzf_function2_( "tex2Dbias",        s, t            ); }
  static ss tex3D           ( char_cptr s, char_cptr t )                              { return zzf_function2_( "tex3D",            s, t            ); }
  static ss tex3D           ( char_cptr s, char_cptr t, char_cptr ddx, char_cptr ddy ){ return zzf_function4_( "tex3D",            s, t, ddx, ddy  ); }
  static ss tex3Dproj       ( char_cptr s, char_cptr t )                              { return zzf_function2_( "tex3Dproj",        s, t            ); }
  static ss tex3Dbias       ( char_cptr s, char_cptr t )                              { return zzf_function2_( "tex3Dbias",        s, t            ); }
  static ss texCUBE         ( char_cptr s, char_cptr t )                              { return zzf_function2_( "texCUBE",          s, t            ); }
  static ss texCUBE         ( char_cptr s, char_cptr t, char_cptr ddx, char_cptr ddy ){ return zzf_function4_( "texCUBE",          s, t, ddx, ddy  ); }
  static ss texCUBEproj     ( char_cptr s, char_cptr t )                              { return zzf_function2_( "texCUBEproj",      s, t            ); }
  static ss texCUBEbias     ( char_cptr s, char_cptr t )                              { return zzf_function2_( "texCUBEbias",      s, t            ); }
  static ss transpose       ( char_cptr m )                                           { return zzf_function1_( "transpose",        m               ); }


  
  // =============================================================================
  // ライン終端
  static css16 Ends;

  // =============================================================================
  // タブカウンタ？
  CPL_SINGLETON_INIT( Core::SStringA<32>, sm_tab_str, "" )
  
  // =============================================================================
  // ブロック用
  class Block {
    ss* ptr_ss = nullptr;
    ss  tmp_ss; // ptr_ss==nullptr時に使用。
  public:
    //Block( CodeFragment* in_ptr_this ) : ptr_ss(&in_ptr_this->gc())
    //{
    //  (*ptr_ss), "{\n";
    //}
    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Block( ss& in_ss )
      : ptr_ss(in_ss.toAddress())
    {
      sm_tab_str() += "\t";

      (*ptr_ss), "{\n";
    }

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Block( std::initializer_list<char_cptr> init )
    {
      for( auto& x : init )
      {
        (tmp_ss, x);
      }
    }

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ~Block()
    {
      sm_tab_str().CutBack( 1 );

      (*ptr_ss), sm_tab_str(), "}\n";
    }

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ss& operator , ( ss& in_str )
    {
      (*ptr_ss), in_str;
      return *ptr_ss;
    }

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    operator char_ptr()
    {
      return ptr_ss ? *ptr_ss : tmp_ss;
    }
    operator char_cptr() const
    {
      return ptr_ss ? *ptr_ss : tmp_ss;
    }
  };

};



#define CPL_HLSL_LOOP(num,counter)\
  For( Int,css32(counter)=css32(0),Ends, css32(counter)<css32(num),Ends, ++css32(counter) ), Block



} // namespace Shader
} // namespace DX
} // namespace CPL
