Boost 1.73.0リリース

Boost 1.73.0がリリースされました。リリースノートはいつものように、boostjpサイトで翻訳 + 情報補完したものを公開しています。

新ライブラリは、WindowsUTF-8出力できるcoutとかが含まれるNowideライブラリ、コンパイル時文字列ライブラリStaticStringの2つです。

今回から、C++03サポートを非推奨化する動きがでてきました。将来的に、サポートされる下限のC++言語バージョンがC++14になりそうです。 世の中のC++解説も、C++14くらいがベースになっていい頃合いなのかもしれません。

Chronoライブラリ最後の日

遊びで調べただけのネタ記事です。

C++20段階の標準時間ライブラリChronoが、西暦何年まで扱えるのかを調べました。

#include <iostream>
#include <chrono>

using namespace std::chrono;

int main() {
    auto tp = system_clock::time_point::max();
    // ほんとはこれでできるはず (できない悲しい)
    // std::cout << tp << std::endl;

    auto dp = floor<days>(tp);
    year_month_day date{dp}; // 日付だけでなく時間もとりたかったけど、hh_mm_ssの実装がない

    // 日付を見てみる
    // ほんとはこう書けるけど、実装がない
    // std::cout << date << std::endl;
    std::cout
        << static_cast<int>(date.year()) << '/' // yearクラスが16ビット符号付き整数で年を管理しているので溢れている
        << static_cast<unsigned int>(date.month()) << '/'
        << static_cast<unsigned int>(date.day())
        << std::endl;

    // 年だけ考えたらどうなるか
    std::cout << floor<years>(system_clock::duration::max()).count() + 1970 << std::endl;

    // time_tでローカル時間を見てみる
    std::time_t t = system_clock::to_time_t(tp);
    std::cout << std::ctime(&t) << std::endl;
}

出力:

32103/1/10
294247
Sun Jan 10 13:00:54 294247

yearクラスの問題がなければ西暦でだいたい約30万年くらいまで扱えるようです。

もしこれが64ビットの符号なし整数で、西暦1970年1月1日から秒単位で数えていたら、西暦6000億年くらいまで扱えます。いまのChronoライブラリのlibc++の実装では、マイクロ秒単位で数えています。また仕様として、符号付き整数型として時間間隔を扱っているのでこうなっています。

符号付きで半分になるので3000億年、マイクロ秒を扱うので1/100万。これでだいたい30万年になります。

結論

C++20段階のlibc++実装のChronoライブラリを使う場合は、だいたい西暦30万年くらいまでにほかの実装に移行してください。

考えられるライブラリ設計の改善点

西暦30万年を超えて生きたい場合は、ライブラリの設計を改善する必要があります。そのために考えられる設計の改善点は、以下のようなことです:

  • system_clock::now()に時間単位を指定できるようにし、秒単位でカウントする。いまは実装定義の時間単位で返されるのでlibc++はマイクロ秒を返している
  • time_pointは時間間隔のdurationと違って1970年より前の日時を扱える必要はないので、符号なしのdurationを扱えるようにする

これで西暦6000億年くらいまで、このライブラリを使えるようになります。

C++ MIX #7 開催案内

cppmix.connpass.com

次回のC++ MIXの日程が決まりました。2020年1月29日 (水) です。

前回、コミュニティの成熟度が上がったと考え、定員を50人ベースから60人ベースに増やしました。

ディスカッションも最初に実施したときの問題をできるだけ改善し、なるべく小さい単位でテーブルを分割して声が届きやすいよう調整しました。今回もまた、当日に柔軟に対応して人数調整や、テーブル移動を促したりしていこうと思います。

Boost 1.72.0リリース

ブログを書くのが一日遅くなりましたが、Boost 1.72.0がリリースされました。

いつものように、boostjpサイトで日本語訳 + 情報補完したものを公開してあります。

C++ MIX #6 開催案内

cppmix.connpass.com

次回のC++ MIXの日程が決まりました。

前回、カジュアルなディスカッションが思った以上に好評だったため、改善を入れつつ今回も継続して行います。

また、翔泳社から出版されている書籍『独習C++』がC++17対応で改訂されることになりましたので、出版記念を兼ねて Flast さんに発表していただきます。書籍を持ってきていただいた方には、著者がサインしてくれるでしょう。(私とzakさんも微力ながらレビューに参加させていただきました)

C++20を相談しながら調べる会 #3

cpp20survey.connpass.com

少し間が空いてしまいましたが、第3回をやります。これが最後になるか、続くのかはまだわかりません。

C++20のCommittee Draftがでたので機能はおそらく出揃いましたが、調べきれるかどうか・・・。

C++標準ライブラリの数学定数への道のり

C++20で数学定数が入ることが決まりましたね。やっと標準ライブラリの範囲で円周率を定数として使えるようになります。

ここまでの道のりですが、

  1. constexpr (C++11)
  2. 変数テンプレート (C++14)
  3. インライン変数 (C++17)
  4. 数学定数 (C++20)

とても長かったですね。

#include <iostream>
#include <numbers>

template <class T>
T degree_to_radian(T x)
{
    return x * std::numbers::pi_v<T> / static_cast<T>(180.0);
}

int main()
{
    float y = degree_to_radian(90.0f);
    std::cout << y << std::endl; // 1.5708
}

constexpr (C++11)

汎用的なコンパイル時計算ができるようになりました。

変数テンプレート (C++14)

constexpr関数では毎回値を計算することになるので、計算済みの値を変数として保持しておくために、テンプレートで変数定義ができるようになりました。

インライン変数 (C++17)

ヘッダファイルで変数を定義してもODR違反にならないよう、翻訳単位を跨いで実体をひとつにするために、インライン変数が導入されました。

これら全てを組み合わせてできた数学定数

// <numbers>ヘッダ
namespace std::numbers {
    // 先行宣言
    template<typename T> inline constexpr T pi_v;

    // 浮動小数点数だけ特殊化して定義
    template <FloatingPoint T>
    inline constexpr T pi_v<T> = (...計算...);

    // デフォルトでdouble
    inline constexpr double pi = pi_v<double>;
}

コンセプトも使われていますが、最終的にこうなりました。

std::numbers::piを使うとdouble型になり、std::numbers::pi_v<T>を使うと任意の浮動小数点数型になります。

非標準のM_PIマクロは昔からありましたが、これからは標準の数学定数が使えます。コンパイラが実装したらね!

次は数学関数のconstexpr化ですね。

Boost 1.71.0リリース

Boost 1.71.0がリリースされました。リリースノートの日本語訳 + 情報補完したものをboostjpサイトで公開しています。

新ライブラリは、Variant2。C++17で標準化されたstd::variantと互換性あるAPIを提供します。ただし、標準のものと違ってvaluelessにはなりません。互換性のためにvalueless_by_exception()関数は用意されますが、常にfalseを返します。

Boost.SmartPtrではenable_shared_from_thisクラスが再設計されました。weak_ptrが最初から考慮されるようになったことに加えて、CRTPを使用したクラステンプレートではなく非テンプレートな基本クラスになりました。boost::enable_shared_fromクラスを継承して使用し、boost::shared_from(this)boost::weak_from(this)のように使用します。

C++ MIX #5 の参加募集を開始しました

cppmix.connpass.com

2019/09/04 (水) になりました。

今回、チャレンジとしてカジュアルなディスカッションの時間を設けてみようと思います。勉強会という場は、モチベーションが高い人が集まっている場だと思うので、多くの参加者が発表を聴いてる、というのはもったいないな、と感じていました。

ディスカッションというと重く聞こえてしまい身構えてしまうかもしれませんが、自分の考えをだれかと話したいとか、深い議論に参加したい (聴いてるだけでもOK) とかができる場にしていきたいと考えています。

今回のチャレンジがうまくいくか、継続してできそうかはまだわかりませんが、一度やってみたいと思います。

C++ MIX #4 の参加募集を開始しました

2019/06/26に開催します。

今回から、勉強会ロゴを正式なものにしました。ロゴはzakさんに作っていただきました。プログラミングの魔導書の表紙、各記事のアイコンからずっとお世話になってます。