Boost 1.74.0がリリースされました。リリースノートはいつものように、boostjpサイトで翻訳 + 情報補完したものを公開しています。
新ライブラリは、STLInterfaces。CRTPベースでコンテナのビュー、イテレータ、シーケンスコンテナを手軽に書けるようにしたライブラリで、Boost.Iteratorの新バージョンと考えられます (Boost.Iterator作者のDave AbrahamsはBoostから離れてしまったので新規書き直し)。
遊びで調べただけのネタ記事です。
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の日程が決まりました。2020年1月29日 (水) です。
前回、コミュニティの成熟度が上がったと考え、定員を50人ベースから60人ベースに増やしました。
ディスカッションも最初に実施したときの問題をできるだけ改善し、なるべく小さい単位でテーブルを分割して声が届きやすいよう調整しました。今回もまた、当日に柔軟に対応して人数調整や、テーブル移動を促したりしていこうと思います。
ブログを書くのが一日遅くなりましたが、Boost 1.72.0がリリースされました。
いつものように、boostjpサイトで日本語訳 + 情報補完したものを公開してあります。
少し間が空いてしまいましたが、第3回をやります。これが最後になるか、続くのかはまだわかりません。
C++20のCommittee Draftがでたので機能はおそらく出揃いましたが、調べきれるかどうか・・・。
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関数では毎回値を計算することになるので、計算済みの値を変数として保持しておくために、テンプレートで変数定義ができるようになりました。
ヘッダファイルで変数を定義しても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がリリースされました。リリースノートの日本語訳 + 情報補完したものを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)
のように使用します。
2019/09/04 (水) になりました。
今回、チャレンジとしてカジュアルなディスカッションの時間を設けてみようと思います。勉強会という場は、モチベーションが高い人が集まっている場だと思うので、多くの参加者が発表を聴いてる、というのはもったいないな、と感じていました。
ディスカッションというと重く聞こえてしまい身構えてしまうかもしれませんが、自分の考えをだれかと話したいとか、深い議論に参加したい (聴いてるだけでもOK) とかができる場にしていきたいと考えています。
今回のチャレンジがうまくいくか、継続してできそうかはまだわかりませんが、一度やってみたいと思います。