2022年4月21日木曜日

Moveの動作

class T
{
public :
	T( void ) { mLogV( L"Constructor") ; }
	T( const T & o ) { mLogV( L"Copy Constructor") ; }
	T( T && o ) { mLogV( L"Move Constructor") ; }

	T &			operator = ( const T & o ) { mLogV( L"Copy Operator") ; return *this ; }
	T &			operator = ( T && o ) { mLogV( L"Move Operator") ; return *this ; }

	static
	T			Func1( tV ) { T o ; return o ; }				// Make系関数 自動でmove扱いになる
	T			Func2( tV ) { return *this ; }					// コピー
	T &			Func3( tV ) { return *this ; }					// 参照 呼び出し元でstd::moveにすると、move扱いに。
//	T &&		FuncX( tV ) { return *this ; }					// コンパイルエラー
	T &&		Func4( tV ) { return std::move( *this ) ; }		// move
//	T &&		FuncX( tV ) { T o ; return o ; }				// コンパイルエラー
	T &&		Func5( tV ) { T o ; return std::move( o ) ; }	// move Func1の強制版。通常ここまでやる必要なし
	static
	T			Func6( T o ) { return o ; }						// 引数は渡し方により、copy、moveを操作可能 returnはmove
	static
	T			Func7( T & o ) { return o ; }					// 引数は参照 returnはcopy
	static
	T			Func8( T && o ) { return o ; }					// 引数はmove returnはmove

} ;
    T o ;							// Constructor

    T o1 = o ;						// Copy Constructor
    T o2 = std::move( o ) ;			// Move Constructor
    T o3 = o.Func1() ;				// Constructor - Move Constructor
    T o4 = o.Func2() ;				// Copy Constructor
    T o5 = o.Func3() ;				// Copy Constructor
    T o6 = std::move( o.Func3()) ;	// Move Constructor
    T o7 = o.Func4() ;				// Move Constructor
    T o8 = o.Func5() ;				// Constructor - Move Constructor

    o = o1;							// Copy Operator
    o1 = std::move( o );			// Move Operator
    o3 = o.Func1() ;				// Constructor - Move Constructor - Move Operator
    o4 = o.Func2() ;				// Copy Constructor - Move Operator
    o5 = o.Func3() ;				// Copy Operator
    o6 = std::move( o.Func3()) ;	// Move Operator
    o7 = o.Func4() ;				// Move Operator
    o8 = o.Func5() ;				// Constructor - Move Operator

	o = T::Func6( o ) ;				// Copy Constructor - Move Constructor - Move Operator
	o = T::Func6( std::move( o )) ;	// Move Constructor - Move Constructor - Move Operator
	o = T::Func6( T()) ;			// Constructor - Move Constructor - Move Operator

	o = T::Func7( o ) ;				// Copy Constructor - Move Operator
//	o = T::Func7( std::move( o )) ;	// コンパイルエラー
//	o = T::Func7( T()) ;			// コンパイルエラー

//	o = T::Func8( o ) ;				// コンパイルエラー
	o = T::Func8( std::move( o )) ;	// Move Constructor - Move Operator
	o = T::Func8( T()) ;			// Constructor - Move Constructor - Move Operator

2019年11月29日金曜日

Luaのテーブル上限

luaのスクリプト形式で永続化情報を出力して、luaに再読み込みさせると
「function at line 1 has more than 65536 constants」
というエラーが返ってきた。

ネットでテーブルの上限を調べてみても、メモリ次第という答えしか見つからなかった。

テストプログラムで実験してみると、配列の要素数、キーの数には制限がなさそうだけど
テーブル要素が65536を超えると、前述のエラーが出る。

o = {
{a=1},
{a=1},
{a=1},
.
. 全部で65536個
.
{a=1},
}
エラー。
oと中身の65536個を足すと65537個になる。中身が65535個ならエラーにならない。

1変数内の最大数が65536までなのかと思い下記のコードを実行
o = {
{a=1},
.
. 全部で35535個
.
{a=1},
}
o2 = {
{a=1},
.
. 全部で30000個
.
{a=1},
}
エラー。
oと中身の35535個、o2と中身の30000個で65537個。
oの中身を35534個にすればエラーにならない。

グローバルスコープで宣言できる数が、65536までらしい。
function x()
o = {
{a=1},
.
. 全部で65535個
.
{a=1},
}
end
g = {
{a=1},
.
. 全部で65533個
.
{a=1},
}
OK。

x関数のスコープ内はoと中身で65536個、グローバルスコープはgと中身で65534個+関数で65536個と数えるらしい。関数は2個扱い?
gの要素数を65534個にするとエラーになる。
x関数内にo2を増やしても、g側の要素数には影響しなかった為、x関数内の変数の数は関係ないようだ。

関数を増やしてみる。
function x()
.
.
.
end
function y()
.
.
.
end
g = {
{a=1},
.
. 全部で65531個
.
{a=1},
}
OK。

x関数、y関数、gと中身の65531個で65536個。
gの中身を65532個にするとエラーになる。
関数を3個に増やした場合、gの要素を65529個にすればエラーにならない。
やはり関数は2個と数えるようだ。

関数を要素に入れてみる。
g = {
{a=1},
.
. 全部で65533個
.
{a=1},
f = function() return {} end
}
エラー。
なぜか、関数を要素に入れる場合は3個で数えるようだ。
gの要素を65532個にするとエラーでなくなる。

関数を2つ入れてみる。
g = {
{a=1},
.
. 全部で65531個
.
{a=1},
f = function() return {} end,
f2 = function() return {} end
}
なぜか、2つ目は2個でエラーにならない。
3つ目も同様で2個扱い。
最初の関数定義だけは、3つで数えるらしい。

最後定義されている関数を入れてみる。
function x() return {} end
g = {
{a=1},
.
. 全部で65531個
.
{a=1},
f = x
}
定義されている関数を追加する場合は1つ目の関数だとしても2つ計算となった。

2017年7月19日水曜日

オーナードローでサブメニューの▶を描画する方法

メニューのオーナードローをした時、どうしても制御できないのがメニューのボーダ部分とサブメニューの▶の部分
いろいろ調べて▶の部分が制御ができるようになった。

オーナードローをしても、枠の灰色の線とSubの隣の▶の色が環境依存で、指定が出来ない。
▶については、通常黒で、選択すると反転して白になる。
左図のような黒背景だと▶が見えない。
DrawItemイベントでは描画しておらず、その後に勝手に描画されるからSetTextColorとか適用されないかな?と思ったけど無視される。

やり方は、ExcludeClipRectでメニュー項目全体をクリップすると、勝手に描画されるのを抑制できるので、あとは自分で描画するだけ。

通常状態でも白で表示出来るようになった。

2017年5月16日火曜日

VS2017のAllocConsoleでUnicode(UTF-16)出力

std::wcout.imbue(std::locale("Japanese")) ;
AllocConsole() ;
FILE * pF = _wfdopen( h, L"w" ) ;
fclose( stdout ) ;
*stdout = *pF;
setvbuf( stdout, NULL, _IONBF, 0 ) ;

VS2010では上記のコードで、wcout、wprintfを使ってコンソール出力が出来た。

VS2017でコンパイルすると、コンパイルは通るが実行すると落ちる。
いろいろ調べてみた結果、_wfreopen(freopen)でstdoutを"CONOUT$"で開き直すとコンソールと紐付けは出来るようだ。

でも、printfすると落ちる。
wprintfすると表示されなかったり、表示されるが16進文字だったり、文字化けしていたり。
wcoutは日本語は表示されるが、"\n"、endlの部分で落ちる。
coutはやってない。
唯一、表示されるのがWriteConsole関数。

試してみたのは下記のキーワード
wcout.imbue
_wsetlocale(setlocale)
setvbuf
_setmode
wcout.rdbuf
SetConsoleOutputCP
sync_with_stdio

どうやってもまともに表示されない。

色々やっているとwcoutで落ちるのは、rdbufが準備できていない?感じで、rdbufを入れ替える方法を見つけたのでwcout以外は全部捨てて対応したコードが下記。

class Out {
private :
class Buf : public std::wstreambuf {
private :
HANDLE h ;
public :
virtual int_type overflow( int_type c = EOF ) override {
if( c == EOF ) return c ;
wchar_t sBuf[] = { c, '\0' } ;
DWORD nW ;
WriteConsole( this->h, sBuf, 1, &nW, NULL ) ;
return c ;
}
Buf( void ) {
this->h = GetStdHandle( STD_OUTPUT_HANDLE ) ;
}
} oBuf ;
std::wstreambuf * pOld ;
public:
Out( void ) { this->pOld = std::wcout.rdbuf( &oBuf ) ; }
~Out( void ) { std::wcout.rdbuf( this->pOld ) ; }
} ;

AllocConsoleした後に、Outクラスのインスタンスを作ると、wcoutのバッファがoverflow関数に1文字ずつ渡ってくるらしい。内部では唯一まともに動くWriteConsoleを呼び出す。

2013年6月24日月曜日

Chrome Secure Shellでペーストの方法

Ctrl+VとかAlt+Vとか試してみるもペーストできない。

スクリーン上の文字列を選択すると、画面の真ん中に
Selection Copied
と表示される。

これが表示されるということはクリップボードの値を貼り付けることが出来るはず。

マニュアルを調べてみたら
Ctrl+Shift+V
だって。

2013年6月4日火曜日

Zlib 1.2.8

zlibのバージョンを1.2.8に上げた所、プログラムが動かなくなった。
デバッグすると、初期化(deflateInit)でエラーが返ってきている。
エラーはZ_STREAM_ERROR。

ネットで検索すると、引数の圧縮レベルが間違っているという。
指定している値はZ_DEFAULT_COMPRESSION(-1)で問題ないはず。
試しに0とか6とか試してみてもダメ。

deflate.cの中までデバッグしてみると、渡している構造体(z_stream)のzallocをチェックしている所でエラーになっている。この値がNULLの場合、Z_SOLOのコンパイルスイッチが定義されていると即エラー。
何らかのアロケート関数を渡す必要があるみたい。
Z_SOLOを定義して無ければzcallocという関数が自動で設定される。

ライブラリのサイズが減ったと思ったら、このへんの関数を削る設定がデフォルトになってたみたい。
元々300KBぐらいで、削減して260KBぐらいになってた。
Windowsデスクトップアプリでは大したサイズではないので、zlibのプロジェクトからZ_SOLOを消してコンパイルし直した所、今までと同じ動作に戻った。

2012年4月3日火曜日

サーバ

さくらのVPSってのがあるらしい。

失敗した。
さっきcoreserver1年更新したばっか。
でも、いまさくらのVPSは1Gと2G大人気過ぎで契約が一時停止中なので、
来年はそっちで更新か。