1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

libcxx での C++11 type_traits ソースコードツアーメモ

Last updated at Posted at 2020-11-06

背景

  • C++11 or later の std::enable_if とかどういう実装になっているのかきになる.
  • C++11 or later の type_traits の知見を増やしたい
  • type_traits を自作したい

ナウでヤングな libcxx(libc++) のソースコードをみてみます.

ちなみに libcxx 全体の行数は header files で 14 万行, source files で 1.3 万行くらいです.
(gcc libstd++ は header で 4.2 万行くらい)

ソースコードは微妙に読みづらいのと, コメントが殆ど無いので, 複雑なものだとどのような理由でそのような実装になっているのかがソースコードからだけではわからないです.
(gcc 7 以降の GNU libstdc++ のほうがまだいくらかコメントあって読みやすい感があります)

あとは, libcxx のいくらかはどうみても libstc++ からパクった感がありますが, ライセンスとかいいんでしょうかね?
(libstdc++ 自体が一部, 昔の STLPort(SGI STL. 覚えているかな!?) あたりからコピってきたのであればまあいいのかもしれません)

std::move

仕様では <utility> ですが,

libcxx では type_traits に実装されています.

基本 &&static_cast しているだけです.

std::forward

こちらも static_cast

std::is_same

__has_keyword(__is_same) かどうかで実装が変わっていますが(__is_same はだいたい clang compiler 向け), コンパイラ固有のコードパスは無視して一般的なほうを見てみます.

template <class _Tp, class _Up> struct _LIBCPP_TEMPLATE_VIS is_same           : public false_type {};
template <class _Tp>            struct _LIBCPP_TEMPLATE_VIS is_same<_Tp, _Tp> : public true_type {};

template 引数が同じ型で展開できるかどうかで判定しています.

std::enable_if

template <bool, class _Tp = void> struct _LIBCPP_TEMPLATE_VIS enable_if {};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS enable_if<true, _Tp> {typedef _Tp type;};

<true, void でないなにか型> のときに実体を作ることで実現しています.

std::remove_const

template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_const            {typedef _Tp type;};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_const<const _Tp> {typedef _Tp type;};

わかりやすいですね.

std::is_void

template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_void
    : public is_same<typename remove_cv<_Tp>::type, void> {};

is_same で void と比較しています.
(void は型として使えるのですね)

std::declval

これも仕様では <utility> ですが実装は type_traits にあります.

ソースコードだけからはちっとも理由がわかりません.

// Suppress deprecation notice for volatile-qualified return type resulting
// from volatile-qualified types _Tp.
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Tp> _Tp&& __declval(int);
template <class _Tp> _Tp   __declval(long);
_LIBCPP_SUPPRESS_DEPRECATED_POP

template <class _Tp>
decltype(_VSTD::__declval<_Tp>(0))
declval() _NOEXCEPT;

ありがとうございます.

でも, int と long で分けているのはなにか理由があるのですかね?(どちらも int でいいようなきも)

ちなみに decltype は C++11 言語仕様(キーワード)で, 式から型を取得します.

その他

libcxx コード頑張って読もう!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?