boost::make_iterator_range_n関数の話です。これを最近見つけました。これは、先頭要素を指すイテレータと要素数を実引数に渡すとRangeオブジェクトを返してくれる関数です。調べてみるとBoost 1.56.0からのものでした。

C言語のAPIでよくある、配列要素へのポインタと要素数という組み合わせをRange化するのに便利です。

#include <array>
#include <iostream>
#include <boost/range/iterator_range.hpp>
#include <windows.h>
#include <wtsapi32.h>
 
#pragma comment(lib, "wtsapi32.lib")
 
int main()
{
  WTS_SESSION_INFO* sessionInfoArray;
  DWORD count;
  if (!WTSEnumerateSessions(
    WTS_CURRENT_SERVER_HANDLE, 0, 1, &sessionInfoArray, &count))
  {
    std::cerr << "Failed" << std::endl;
    std::quick_exit(1);
  }
  // sessionInfoArray[0]からsessionInfoArray[count - 1]に
  // データが書き込まれている。
 
  for (const WTS_SESSION_INFO& info
    : boost::make_iterator_range_n(sessionInfoArray, count))
  {
    std::cout << info.SessionId
      << ' ' << info.pWinStationName << std::endl;
  }
  std::quick_exit(0);
  // WTSFreeMemoryは省略
}

main関数の仮引数argcとargvに対しても使えます。

#include <iostream>
#include <boost/range/iterator_range.hpp>
 
int main(int argc, char** argv)
{
  // なお、argv[0]を除外したければ
  // boost::make_iterator_range_n(argv + 1, argc - 1)とすれば良い。
  auto r = boost::make_iterator_range_n(argv, argc);
  for (auto arg : r)
  {
    std::cout << arg << std::endl;
  }
}

以前より、先頭と終端(の次)のイテレータ2つからRangeを作ってくれるboost::make_iterator_range関数がありました。これを使って、boost::make_iterator_range(sessionInfoArray, sessionInfoArray + count)やmake_iterator_range(argv, argv + argc)というコードを良く書いていました。そのため、こういう関数が欲しいなあと思っていたところだったので、すでに存在していて嬉しいです。


スポンサード リンク

この記事のカテゴリ

  • ⇒ 配列要素へのポインタと要素数からRangeを作る