2016年2月26日

Windowsがサーバ版かどうかを調べる

プログラムが動作している環境(Windows)がサーバ版かどうかを調べたいことがまれにあります(WMIでサーバ版Windowsではサポートされていない項目の問い合わせをするときなど)。RTLのソースをちょっと覗いてみたところ、Win32APIのGetVersionEx (ja)関数で取得したOSVERSIONINFOEX構造体のwProductTypeがVER_NT_WORKSTATIONかどうかで判断できるようなのですが、GetVersionEx関数のRemarksにはVerifyVersionInfo (ja)関数を使ったほうがパフォーマンス上望ましい、と書いてあるようなので、VerifyVersionInfo関数(とそのパラメータを組み立てるためにVerSetConditionMask関数の組み合わせ)で実現してみました。
function IsWindowsServer: Boolean;
var
  OSVI: TOSVersionInfoEx;
  ConditionMask: UInt64;
begin

  FillChar(OSVI,SizeOf(TOSVersionInfoEX),0);
  OSVI.dwOSVersionInfoSize := SizeOf(OSVI);
  OSVI.wProductType := VER_NT_WORKSTATION;

  ConditionMask := VerSetConditionMask(0,VER_PRODUCT_TYPE,VER_EQUAL);

  Result := not (VerifyVersionInfo(OSVI,VER_PRODUCT_TYPE,ConditionMask));

end;
OSVERSIONINFOEX構造体を初期化後、wProductTypeにVER_NT_WORKSTATIONを格納し、これに対応する条件マスク(VER_PRODUCT_TYPEがVER_EQUAL)をVerifyVersionInfoで作成してVerifyVersionInfoで問い合わせて、結果がFalse(wProductTypeがVER_NT_WORKSTATION以外)ならサーバ版Windows、という判定です。

Windowsがサーバ版かどうかを調べる(Gist)

2016年2月12日

RAD Studio/Delphi/C++Builder XE7 December 2015 Update

RAD Studio/Delphi/C++Builder XE7のDecember 2015 Updateがリリースされています。有効なアップデートサブスクリプションが必要です。

30477 December 2015 XE7 Update Subscription Update

10 Seattle アップデートサブスクリプション加入ユーザー向け「December 2015 XE7 Update Subscription Update」

RAD Studio/Delphi/C++Builder XE8 December 2015 Update

RAD Studio/Delphi/C++Builder XE8のDecember 2015 Updateがリリースされています。有効なアップデートサブスクリプションが必要です。

30476 December 2015 XE8 Update Subscription Update

10 Seattle アップデートサブスクリプション加入ユーザー向け「December 2015 XE8 Update Subscription Update」

2016年2月10日

2016年2月9日

RAD Studio 2016 ロードマップ

RAD Studioのロードマップは1年くらい前に更新されてそのままになっていました。2015年05月のデベロッパーキャンプのときにMarco Cantuさんに『ロードマップの更新は?』と聞いたところ、『モバイル関係の流れが速いのでロードマップを出すのは難しい』という回答でした(それは困る、とは伝えましたが)。しかし2015年秋のIDERAによる買収によって路線の修正が行われ、2016年01月にロードマップを更新する、というAtanas Popovさんの発言もあり、1月末くらいからどうなってるの?という声も出ていましたが、やっとロードマップが更新されました。

Embarcadero RAD Studio 2016 Product Approach and Roadmap

以下今後のリリースに関する適当な要約:
  • 2016年春リリースのコードネーム"Big Ben"のキーテーマは"品質、最初のユーザ体験と導入"で、新しいインストーラとGetItによりインストールの柔軟性とインストール時間の短縮を図る。2016年のリリースに以下の機能を含めるためチームは作業をしている。
    • VCLとFMXの両方でフォームデザイナをセパレート/フロート可能に
    • C++に関するリファクタリング
    • FireUIアプリケーションプレビュー(IDEのフォームデザイナであらゆるターゲット上でのプレビュー)
    • Firemonkeyの拡張
      • アドレス帳/コンタクトコンポーネント
      • スタイルデザイナとリストビューアイテムデザイナ
      • 多くの機能、リストビューのタッチアニメーション、グリッドの改善、Windowsのアクセラレータキーのサポート、フォント拡張、その他
    • マルチデバイスデザイナの改善
        デバイス上のフォームデザイナプレビュー
      • Android Wearスタイルと新しいFireUIビュー
    • IoT (Internet of Things)
      • Bluetooth LEサポートの拡張
      • そのままでもカスタムでもIoTスマートデバイス、センサ、ウェアラブルを簡単に使えるAPIコンポーネントであるIoT接続フレームワーク
      • Bluetooth LEおよびZ-Waveデバイスをサポートするコンポーネント
      • ThingPoint(EMS機能を拡張するIoTデバイスのためのエンタープライズなアクセスポイント)
    • Windows/VCL
      • Windows 10のBluetooth LEサポートを含むWinRTブリッジの改善
      • DirectX 12サポート
    • Delphiコンパイラおよび言語
      • すべてのプラットフォーム上でUtf8Stringをネイティブサポート
      • Windowsなど非ARCプラットフォーム上でのweak/unsafeインタフェース参照のサポート
    • すべてのプラットフォームでC++ Clang 3.3に移行
    • FireDACドライバ更新(Oracle、DB2、InterBase、SQLite、Advantage)
  • その次の2016年秋リリースのコードネーム"Godzilla"ではDelphi/C++BuilderアプリケーションがLinux上で動くようになる。夏にはDelphi for Linuxのテクニカルプレビューを出すのでぜひフィードバックしていただいて、可能な限り安定して強固なものにしていきたい。秋のリリースを目標としているものは以下の通り。
    • WebBrokerによるApacheモジュールとDataSnap/EMSサポート
    • FireDACによるLinuxデータベースアクセス
    • IoTサポートを含むコンソールアプリケーションのLinuxプラットフォームサポート
    • 公式にはUbuntu ServerとRedHat Enterpriseをサポート(これ以外のディストリビューションの公式サポートは需要に応じて広げてゆく)
    • WindowsベースのIDEとクロスコンパイラ、PAServer経由のデプロイとデバッグ
    • LinuxコンパイラはIntel 64ビットサーバ用で、LLVMベースのARCサポート
  • Linuxサポートの後についてはさらに以下のようなものを考えている。
    • IDEのUIの改善とスタイル
    • すべてのC++コンパイラをより新しいClangベースのものに更新
    • パッケージマネージャおよびインストーラとしての両方でGetItの更なる改善
    • 新しいWindows 10のVCLコンポーネント
    • Firemonkeyのネイティブコントロールの更なる改善
    • Windows 10 Centennialサポート(MicrosoftによるCentennial ユニバーサルWindowsプラットフォームブリッジのリリース待ち)
    • 将来のiOSおよびAndroidのバージョンのサポート

公式の日本語訳も出ました(つか負けた)。

Embarcadero RAD Studio 2016年の製品アプローチとロードマップ

2016年2月5日

整数の中で立っているビットの数を数える

それほど機会が多いわけではありませんが、整数の中で立っているビットの数を数えたいということがあります。C++であればstd::bitsetcountを使えば一発ですが、残念ながらDelphiでは符号なし整数型のヘルパ(TByteHelper/TWordHelper/TCardinalHelper/TUInt64Helper)を含め、標準ではそのような機能がありません。でちょっと検索してみたところ、population countあるいはHamming weightというキーワードが浮かんできました。最近のCPUには専用の命令(x86だとSSE4.2以降のPOPCNT)がありますが、移植性などを考慮して、Delphiで実装してみました。とはいってもCで書かれたものをそのままDelphiに置き換えただけです。詳細や原理については○×つくろーどっとコムさんのその17 ビット演算あれこれ中村実さんのビットを数える・探すアルゴリズムなどを、またx86/x64のPOPCNT命令との比較についてはtakesakoさんのx86x64 SSE4.2 POPCNTあたりを参照してください。
function PopulationCount(Value: UInt8): Integer;
begin

  Value := (Value and $55) + ((Value shr 1) and $55);
  Value := (Value and $33) + ((Value shr 2) and $33);
  Value := (Value and $0F) + ((Value shr 4) and $0F);
  Result := Value;

end;

function PopulationCount(Value: UInt16): Integer;
begin

  Value := (Value and $5555) + ((Value shr 1) and $5555);
  Value := (Value and $3333) + ((Value shr 2) and $3333);
  Value := (Value and $0F0F) + ((Value shr 4) and $0F0F);
  Value := (Value and $00FF) + ((Value shr 8) and $00FF);
  Result := Value;

end;

function PopulationCount(Value: UInt32): Integer;
begin

  Value := (Value and $55555555) + ((Value shr  1) and $55555555);
  Value := (Value and $33333333) + ((Value shr  2) and $33333333);
  Value := (Value and $0F0F0F0F) + ((Value shr  4) and $0F0F0F0F);
  Value := (Value and $00FF00FF) + ((Value shr  8) and $00FF00FF);
  Value := (Value and $0000FFFF) + ((Value shr 16) and $0000FFFF);
  Result := Value;

end;

function PopulationCount(Value: UInt64): Integer;
begin

  Value := (Value and $5555555555555555) + ((Value shr  1) and $5555555555555555);
  Value := (Value and $3333333333333333) + ((Value shr  2) and $3333333333333333);
  Value := (Value and $0F0F0F0F0F0F0F0F) + ((Value shr  4) and $0F0F0F0F0F0F0F0F);
  Value := (Value and $00FF00FF00FF00FF) + ((Value shr  8) and $00FF00FF00FF00FF);
  Value := (Value and $0000FFFF0000FFFF) + ((Value shr 16) and $0000FFFF0000FFFF);
  Value := (Value and $00000000FFFFFFFF) + ((Value shr 32) and $00000000FFFFFFFF);
  Result := Value;

end;
整数の中で立っているビットの数を数える(Gist)

2020/06/01追記: Delphi 10.4 Sydneyでは標準関数(かつ組み込みルーチン(en))としてCountLeadingZeros32(先頭の(MSBからの)連続している0の数/32bit整数)、CountLeadingZeros64(先頭の(MSBからの)連続している0の数/64bit整数)、CountTrailingZeros32(末尾のの(LSBからの)連続している0の数/32bit整数)、CountTrailingZeros64(末尾のの(LSBからの)連続している0の数/64bit整数)、CountPopulation32(1になっているビットの数/32bit整数)、CountPopulation64(1になっているビットの数/64bit整数)が追加されました。これらの関数はコンパイラによってインラインで展開されるため、System.pasなどに定義がありません。またこれらの関数は現時点ではヘルプ上に記述がありません。

2016年2月1日