SlideShare a Scribd company logo
1 of 20
Download to read offline
C++0xの可変引数テンプレートで
       型リスト処理

                           高橋晶(アキラ)

   ブログ:「Faith and Brave – C++で遊ぼう」
    http://d.hatena.ne.jp/faith_and_brave/
可変引数テンプレート
template <class... Args>
class tuple;


のように書くことで
テンプレートパラメータを可変個
受け取ることができる

tuple<int>             t1;
tuple<int, long>       t2;
tuple<int, long, char> t3;

可変個のテンプレートパラメータは型のリストと見なせる
型リストを処理するメタ関数を
            作ってみた
•   head, tail
•   length
•   at
•   concat
•   reverse
•   replicate
•   take, drop
•   map, filter
•   tale_while, drop_while
•   all, any
head : 型リストの先頭
           tail : 型リストの後部
template <class Head, class... Tail>
struct head {
   typedef Head type;
};

template <class Head, class... Tail>
struct tail {
   typedef tuple<Tail...> type;
};

head<int, long, char>::type
→ int

tail<int, long, char>::type
→ tuple<long, char>
head, tailのtuple版
tupleの部分特殊化も用意しておく

template <class Head, class... Tail>
struct head<tuple<Head, Tail...>> {
  typedef Head type;
};

// 型リストから後部の型リストを取得
template <class Head, class... Tail>
struct tail<tuple<Head, Tail...>> {
  typedef tuple<Tail...> type;
};

head<tuple<int, long, char>>::type
→ int

tail<tuple<int, long, char>>::type
→ tuple<long, char>
length : 型リストの長さ
template <class... Args>
struct length {
  static const int value = sizeof...(Args);
};

template <class... Args>
struct length<tuple<Args...>> {
  static const int value = sizeof...(Args);
};

length<int, long, char>::value
→ 3

length<tuple<int, long, char>>::value
→ 3
at : 型リストのI番目
ここからはめんどくさいからtuple版のみ

template <int I, typename Arg>
struct at;

template <int I, typename Head, typename... Tail>
struct at<I, tuple<Head, Tail...>> {
   typedef typename at<I - 1, tuple<Tail...>>::type type;
};

template <class Head, typename... Tail>
struct at<0, tuple<Head, Tail...>> {
   typedef Head type;
};

at<1, tuple<int, long, char>>::type
→ long
concat : 型リストの連結
template <class Seq1, class Seq2>
struct concat;

template <class... Seq1, class... Seq2>
struct concat<tuple<Seq1...>, tuple<Seq2...>> {
  typedef tuple<Seq1..., Seq2...> type;
};

concat<tuple<int, double>,
       tuple<long, char>>::type

→ tuple<int, double, long, char>
reverse : 型リストを逆順にする
型の長さ分だけ再帰して、先頭を後ろに追加していく

template <int N, class Seq>
struct reverse_impl;

template <int N, class Head, class... Tail>
struct reverse_impl<N, tuple<Head, Tail...>> {
  typedef
    typename concat<typename reverse_impl<N-1, tuple<Tail...>>::type,
                    tuple<Head>
             >::type
  type;
};

template <class... Seq>
struct reverse_impl<0, tuple<Seq...>> {
  typedef tuple<Seq...> type;
};
reverse : 型リストを逆順にする
template <class Seq>
struct reverse;

template <class... Seq>
struct reverse<tuple<Seq...>> {
  typedef typename reverse_impl<sizeof...(Seq), tuple<Seq...>>::type type;
};

reverse<tuple<int, double, long>>::type
→ tuple<long, double, int>
replicate : TをN個含んだ型リストを作成
N個分だけ再帰してconcatで型を追加していく

template <int N, class T>
struct replicate {
  typedef
    typename concat<typename replicate<N-1, T>::type,
                    tuple<T>
             >::type
  type;
};

template <class T>
struct replicate<0, T> {
  typedef tuple<> type;
};

replicate<3, int>::type
→ tuple<int, int, int>
take : 先頭N個の型を取得
template <int N, class Seq>
struct take;

template <int N, class Head, class... Tail>
struct take<N, tuple<Head, Tail...>> {
   typedef
     typename concat<tuple<Head>,
                     typename take<N-1, tuple<Tail...>>::type
              >::type
   type;
};

template <class Head, class... Tail>
struct take<1, tuple<Head, Tail...>> {
   typedef tuple<Head> type;
};

template <class Head, class... Tail>
struct take<0, tuple<Head, Tail...>> {
   typedef tuple<> type;
};

take<3, tuple<int, double, long, char, void*>>::type
→ tuple<int, double, long>
drop : 先頭N個を除外した型リストを取得
template <int N, class Seq>
struct drop;

template <int N, class Head, class... Tail>
struct drop<N, tuple<Head, Tail...>> {
  typedef
    typename drop<N-1, tuple<Tail...>>::type
  type;
};

template <class Head, class... Tail>
struct drop<0, tuple<Head, Tail...>> {
  typedef tuple<Head, Tail...> type;
};


drop<3, tuple<int, double, long, char, void*>>::type
→ tuple<char, void*>
map : 型リストの全ての型にメタ関数を適用
mapはメタ関数をパラメータで受け取る高階メタ関数
メタ関数は、テンプレートテンプレートパラメータで受け取る

template <template <class T> class F, class... Seq>
struct map;

template <template <class T> class F, class... Seq>
struct map<F, tuple<Seq...>> {
  typedef tuple<typename F<Seq>::type...> type;
};


template <class T>
struct add_pointer {
   typedef T* type;
};

map<add_pointer, tuple<int, double, long>>::type
→ tuple<int*, double*, long*>
filter : 条件抽出(1)
まず、条件を満たす場合のみ型リストに型を追加するメタ関数を用意する

template <bool B, class T, class Seq>
struct add_if_c;

template <class T, class... Seq>
struct add_if_c<true, T, tuple<Seq...>> {
    typedef tuple<Seq..., T> type;
};

template <class T, class... Seq>
struct add_if_c<false, T, tuple<Seq...>> {
    typedef tuple<Seq...> type;
};


template <template <class> class P, class T, class... Seq>
struct add_if;

template <template <class> class P, class T, class... Seq>
struct add_if<P, T, tuple<Seq...>> :
    public add_if_c<P<T>::value, T, tuple<Seq...>> {};
filter : 条件抽出(2)
add_ifを使って、述語を満たす型のみの型リストを作成

template <template <class T> class P, class Seq1, class Seq2>
struct filter_impl;

template <template <class T> class P, class... Seq, class Head, class... Tail>
struct filter_impl<P, tuple<Seq...>, tuple<Head, Tail...>> {
    typedef
        typename filter_impl<P,
                             typename add_if<P,
                                             Head,
                                             tuple<Seq...>>::type,
                             tuple<Tail...>>::type
    type;
};

template <template <class T> class P, class... Seq>
struct filter_impl<P, tuple<Seq...>, tuple<>> {
    typedef tuple<Seq...> type;
};


template <template <class T> class P, class... Seq>
struct filter;

template <template <class T> class P, class... Seq>
struct filter<P, tuple<Seq...>> {
    typedef typename filter_impl<P, tuple<>, tuple<Seq...>>::type type;
};

filter<is_integral, tuple<int, double, long>>::type
→ tuple<int, long>
take_while : 条件を満たす先頭部分を取り出す
template <template <class T> class P, class Seq1, class Seq2>
struct take_while_impl;

template <template <class T> class P, class... Seq, class Head, class... Tail>
struct take_while_impl<P, tuple<Seq...>, tuple<Head, Tail...>> {
   typedef typename
     if_c<P<Head>::value,
          typename take_while_impl<P,
                                   typename concat<tuple<Seq...>, tuple<Head>>::type,
                                   tuple<Tail...>
                    >::type,
          tuple<Seq...>
     >::type
   type;
};

template <template <class T> class P, class... Seq>
struct take_while_impl<P, tuple<Seq...>, tuple<>> {
   typedef tuple<Seq...> type;
};


template <template <class T> class P, class Seq>
struct take_while;

template <template <class T> class P, class... Seq>
struct take_while<P, tuple<Seq...>> {
   typedef typename take_while_impl<P, tuple<>, tuple<Seq...>>::type type;
};


take_while<is_integral, tuple<int, long, char, double>>::type
→ tuple<int, long, char>
drop_while : 条件を満たす先頭部分を取り出す
template <template <class T> class P, class Seq>
struct drop_while;

template <template <class T> class P, class Head, class... Tail>
struct drop_while<P, tuple<Head, Tail...>> {
  typedef
    typename if_c<P<Head>::value, // trueだったら
                  typename drop_while<P, tuple<Tail...>>::type, // 無視する
                  tuple<Head, Tail...>
             >::type
  type;
};

template <template <class T> class P>
struct drop_while<P, tuple<>> {
  typedef tuple<> type;
};

drop_while<is_integral, tuple<int, long, char, double>>::type
→ tuple<double>
all : 型リストの要素全てが述語を満たすか
型リストの全ての型が述語を満たせばtrue
それ以外はfalseを返す

template <template <class T> class P, class Seq>
struct all;

template <template <class T> class P, class Head, class... Tail>
struct all<P, tuple<Head, Tail...>> {
   static const bool value = !P<Head>::value ?
                             false :
                             all<P, tuple<Tail...>>::value;
};

template <template <class T> class P>
struct all<P, tuple<>> {
   static const bool value = true;
};


all<is_integral, tuple<int, long, char>>::value
→ true

all<is_integral, tuple<int, double, char>>::value
→ false
any :型リストに述語を満たす型があるか
型リストのいずれかの型が述語を満たせばtrue
それ以外はfalseを返す

template <template <class T> class P, class Seq>
struct any;

template <template <class T> class P, class Head, class... Tail>
struct any<P, tuple<Head, Tail...>> {
   static const bool value = P<Head>::value ?
                             true :
                             any<P, tuple<Tail...>>::value;
};

template <template <class T> class P>
struct any<P, tuple<>> {
   static const bool value = false;
};

any<is_integral, tuple<int, long, char>>::value
→ true

any<is_integral, tuple<float, int, void*>>::value
→ true

any<is_integral, tuple<float, double, void*>>::value
→ false

More Related Content

What's hot

Introduction to Python for Plone developers
Introduction to Python for Plone developersIntroduction to Python for Plone developers
Introduction to Python for Plone developersJim Roepcke
 
Coding Guidelines - Crafting Clean Code
Coding Guidelines - Crafting Clean CodeCoding Guidelines - Crafting Clean Code
Coding Guidelines - Crafting Clean CodeGanesh Samarthyam
 
Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7Paulo Morgado
 
Python decorators
Python decoratorsPython decorators
Python decoratorsAlex Su
 
Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.
Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.
Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.Samuel Fortier-Galarneau
 
Decorators in Python
Decorators in PythonDecorators in Python
Decorators in PythonBen James
 
Python Style Guide
Python Style GuidePython Style Guide
Python Style GuideJiayun Zhou
 
String and string manipulation x
String and string manipulation xString and string manipulation x
String and string manipulation xShahjahan Samoon
 

What's hot (17)

Cheat Sheet java
Cheat Sheet javaCheat Sheet java
Cheat Sheet java
 
Strings v.1.1
Strings v.1.1Strings v.1.1
Strings v.1.1
 
php string part 4
php string part 4php string part 4
php string part 4
 
Introduction to Python for Plone developers
Introduction to Python for Plone developersIntroduction to Python for Plone developers
Introduction to Python for Plone developers
 
Coding Guidelines - Crafting Clean Code
Coding Guidelines - Crafting Clean CodeCoding Guidelines - Crafting Clean Code
Coding Guidelines - Crafting Clean Code
 
Python idiomatico
Python idiomaticoPython idiomatico
Python idiomatico
 
Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7
 
Advanced Python : Decorators
Advanced Python : DecoratorsAdvanced Python : Decorators
Advanced Python : Decorators
 
Python decorators
Python decoratorsPython decorators
Python decorators
 
Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.
Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.
Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.
 
Scala Paradigms
Scala ParadigmsScala Paradigms
Scala Paradigms
 
Java generics
Java genericsJava generics
Java generics
 
Data type2 c
Data type2 cData type2 c
Data type2 c
 
Decorators in Python
Decorators in PythonDecorators in Python
Decorators in Python
 
Template Haskell
Template HaskellTemplate Haskell
Template Haskell
 
Python Style Guide
Python Style GuidePython Style Guide
Python Style Guide
 
String and string manipulation x
String and string manipulation xString and string manipulation x
String and string manipulation x
 

Viewers also liked

俺的英語・中国語の勉強法を晒してみる 2011 10-12
俺的英語・中国語の勉強法を晒してみる 2011 10-12俺的英語・中国語の勉強法を晒してみる 2011 10-12
俺的英語・中国語の勉強法を晒してみる 2011 10-12俊仁 小林
 
C++ Template Metaprogramming
C++ Template MetaprogrammingC++ Template Metaprogramming
C++ Template MetaprogrammingAkira Takahashi
 
大学でC++03を教わった私が、便利そうだと思ったC++11の新機能
大学でC++03を教わった私が、便利そうだと思ったC++11の新機能大学でC++03を教わった私が、便利そうだと思ったC++11の新機能
大学でC++03を教わった私が、便利そうだと思ったC++11の新機能tSURooT
 
エクストリームC++11/14プログラミング
エクストリームC++11/14プログラミングエクストリームC++11/14プログラミング
エクストリームC++11/14プログラミングegtra
 
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14Ryo Suzuki
 

Viewers also liked (8)

俺的英語・中国語の勉強法を晒してみる 2011 10-12
俺的英語・中国語の勉強法を晒してみる 2011 10-12俺的英語・中国語の勉強法を晒してみる 2011 10-12
俺的英語・中国語の勉強法を晒してみる 2011 10-12
 
C++1z draft
C++1z draftC++1z draft
C++1z draft
 
C++ Template Metaprogramming
C++ Template MetaprogrammingC++ Template Metaprogramming
C++ Template Metaprogramming
 
大学でC++03を教わった私が、便利そうだと思ったC++11の新機能
大学でC++03を教わった私が、便利そうだと思ったC++11の新機能大学でC++03を教わった私が、便利そうだと思ったC++11の新機能
大学でC++03を教わった私が、便利そうだと思ったC++11の新機能
 
エクストリームC++11/14プログラミング
エクストリームC++11/14プログラミングエクストリームC++11/14プログラミング
エクストリームC++11/14プログラミング
 
What is template
What is templateWhat is template
What is template
 
C++14 Overview
C++14 OverviewC++14 Overview
C++14 Overview
 
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
 

Similar to C++0x Variadic Type List

2 BytesC++ course_2014_c13_ templates
2 BytesC++ course_2014_c13_ templates2 BytesC++ course_2014_c13_ templates
2 BytesC++ course_2014_c13_ templateskinan keshkeh
 
Types, classes and concepts
Types, classes and conceptsTypes, classes and concepts
Types, classes and conceptsNicola Bonelli
 
Templates in C++
Templates in C++Templates in C++
Templates in C++Tech_MX
 
C++ extension methods
C++ extension methodsC++ extension methods
C++ extension methodsphil_nash
 
Preprocessor Programming
Preprocessor ProgrammingPreprocessor Programming
Preprocessor Programminglactrious
 
Templates presentation
Templates presentationTemplates presentation
Templates presentationmalaybpramanik
 
[KOSSA] C++ Programming - 16th Study - STL #2
[KOSSA] C++ Programming - 16th Study - STL #2[KOSSA] C++ Programming - 16th Study - STL #2
[KOSSA] C++ Programming - 16th Study - STL #2Seok-joon Yun
 
any idea#includeiostream using stdcout; using stdendl; .pdf
any idea#includeiostream using stdcout; using stdendl; .pdfany idea#includeiostream using stdcout; using stdendl; .pdf
any idea#includeiostream using stdcout; using stdendl; .pdfpetercoiffeur18
 
[OLD VERSION, SEE DESCRIPTION FOR THE NEWER VERSION LINK] Hot С++: Universal ...
[OLD VERSION, SEE DESCRIPTION FOR THE NEWER VERSION LINK] Hot С++: Universal ...[OLD VERSION, SEE DESCRIPTION FOR THE NEWER VERSION LINK] Hot С++: Universal ...
[OLD VERSION, SEE DESCRIPTION FOR THE NEWER VERSION LINK] Hot С++: Universal ...Andrey Upadyshev
 
Hot С++: Universal References And Perfect Forwarding
Hot С++: Universal References And Perfect ForwardingHot С++: Universal References And Perfect Forwarding
Hot С++: Universal References And Perfect ForwardingAndrey Upadyshev
 
C++11 - A Change in Style - v2.0
C++11 - A Change in Style - v2.0C++11 - A Change in Style - v2.0
C++11 - A Change in Style - v2.0Yaser Zhian
 

Similar to C++0x Variadic Type List (20)

2 BytesC++ course_2014_c13_ templates
2 BytesC++ course_2014_c13_ templates2 BytesC++ course_2014_c13_ templates
2 BytesC++ course_2014_c13_ templates
 
C++ Templates. SFINAE
C++ Templates. SFINAEC++ Templates. SFINAE
C++ Templates. SFINAE
 
Types, classes and concepts
Types, classes and conceptsTypes, classes and concepts
Types, classes and concepts
 
C++ metaprogramming
C++ metaprogrammingC++ metaprogramming
C++ metaprogramming
 
Templates in C++
Templates in C++Templates in C++
Templates in C++
 
C++ metaprogramming
C++ metaprogrammingC++ metaprogramming
C++ metaprogramming
 
C++ extension methods
C++ extension methodsC++ extension methods
C++ extension methods
 
Templates
TemplatesTemplates
Templates
 
Preprocessor Programming
Preprocessor ProgrammingPreprocessor Programming
Preprocessor Programming
 
Templates presentation
Templates presentationTemplates presentation
Templates presentation
 
Templates2
Templates2Templates2
Templates2
 
[KOSSA] C++ Programming - 16th Study - STL #2
[KOSSA] C++ Programming - 16th Study - STL #2[KOSSA] C++ Programming - 16th Study - STL #2
[KOSSA] C++ Programming - 16th Study - STL #2
 
any idea#includeiostream using stdcout; using stdendl; .pdf
any idea#includeiostream using stdcout; using stdendl; .pdfany idea#includeiostream using stdcout; using stdendl; .pdf
any idea#includeiostream using stdcout; using stdendl; .pdf
 
2CPP15 - Templates
2CPP15 - Templates2CPP15 - Templates
2CPP15 - Templates
 
Coding Guidelines in CPP
Coding Guidelines in CPPCoding Guidelines in CPP
Coding Guidelines in CPP
 
[OLD VERSION, SEE DESCRIPTION FOR THE NEWER VERSION LINK] Hot С++: Universal ...
[OLD VERSION, SEE DESCRIPTION FOR THE NEWER VERSION LINK] Hot С++: Universal ...[OLD VERSION, SEE DESCRIPTION FOR THE NEWER VERSION LINK] Hot С++: Universal ...
[OLD VERSION, SEE DESCRIPTION FOR THE NEWER VERSION LINK] Hot С++: Universal ...
 
Templates
TemplatesTemplates
Templates
 
Hot С++: Universal References And Perfect Forwarding
Hot С++: Universal References And Perfect ForwardingHot С++: Universal References And Perfect Forwarding
Hot С++: Universal References And Perfect Forwarding
 
C++11 - A Change in Style - v2.0
C++11 - A Change in Style - v2.0C++11 - A Change in Style - v2.0
C++11 - A Change in Style - v2.0
 
C++11 - STL Additions
C++11 - STL AdditionsC++11 - STL Additions
C++11 - STL Additions
 

More from Akira Takahashi

More from Akira Takahashi (20)

Cpp20 overview language features
Cpp20 overview language featuresCpp20 overview language features
Cpp20 overview language features
 
Cppmix 02
Cppmix 02Cppmix 02
Cppmix 02
 
Cppmix 01
Cppmix 01Cppmix 01
Cppmix 01
 
Modern C++ Learning
Modern C++ LearningModern C++ Learning
Modern C++ Learning
 
cpprefjp documentation
cpprefjp documentationcpprefjp documentation
cpprefjp documentation
 
Boost tour 1_61_0 merge
Boost tour 1_61_0 mergeBoost tour 1_61_0 merge
Boost tour 1_61_0 merge
 
Boost tour 1_61_0
Boost tour 1_61_0Boost tour 1_61_0
Boost tour 1_61_0
 
error handling using expected
error handling using expectederror handling using expected
error handling using expected
 
Boost tour 1.60.0 merge
Boost tour 1.60.0 mergeBoost tour 1.60.0 merge
Boost tour 1.60.0 merge
 
Boost tour 1.60.0
Boost tour 1.60.0Boost tour 1.60.0
Boost tour 1.60.0
 
Boost container feature
Boost container featureBoost container feature
Boost container feature
 
Boost Tour 1_58_0 merge
Boost Tour 1_58_0 mergeBoost Tour 1_58_0 merge
Boost Tour 1_58_0 merge
 
Boost Tour 1_58_0
Boost Tour 1_58_0Boost Tour 1_58_0
Boost Tour 1_58_0
 
C++14 solve explicit_default_constructor
C++14 solve explicit_default_constructorC++14 solve explicit_default_constructor
C++14 solve explicit_default_constructor
 
C++14 enum hash
C++14 enum hashC++14 enum hash
C++14 enum hash
 
Multi paradigm design
Multi paradigm designMulti paradigm design
Multi paradigm design
 
Start Concurrent
Start ConcurrentStart Concurrent
Start Concurrent
 
Programmer mind
Programmer mindProgrammer mind
Programmer mind
 
Boost.Study 14 Opening
Boost.Study 14 OpeningBoost.Study 14 Opening
Boost.Study 14 Opening
 
Executors and schedulers
Executors and schedulersExecutors and schedulers
Executors and schedulers
 

C++0x Variadic Type List

  • 1. C++0xの可変引数テンプレートで 型リスト処理 高橋晶(アキラ) ブログ:「Faith and Brave – C++で遊ぼう」 http://d.hatena.ne.jp/faith_and_brave/
  • 2. 可変引数テンプレート template <class... Args> class tuple; のように書くことで テンプレートパラメータを可変個 受け取ることができる tuple<int> t1; tuple<int, long> t2; tuple<int, long, char> t3; 可変個のテンプレートパラメータは型のリストと見なせる
  • 3. 型リストを処理するメタ関数を 作ってみた • head, tail • length • at • concat • reverse • replicate • take, drop • map, filter • tale_while, drop_while • all, any
  • 4. head : 型リストの先頭 tail : 型リストの後部 template <class Head, class... Tail> struct head { typedef Head type; }; template <class Head, class... Tail> struct tail { typedef tuple<Tail...> type; }; head<int, long, char>::type → int tail<int, long, char>::type → tuple<long, char>
  • 5. head, tailのtuple版 tupleの部分特殊化も用意しておく template <class Head, class... Tail> struct head<tuple<Head, Tail...>> { typedef Head type; }; // 型リストから後部の型リストを取得 template <class Head, class... Tail> struct tail<tuple<Head, Tail...>> { typedef tuple<Tail...> type; }; head<tuple<int, long, char>>::type → int tail<tuple<int, long, char>>::type → tuple<long, char>
  • 6. length : 型リストの長さ template <class... Args> struct length { static const int value = sizeof...(Args); }; template <class... Args> struct length<tuple<Args...>> { static const int value = sizeof...(Args); }; length<int, long, char>::value → 3 length<tuple<int, long, char>>::value → 3
  • 7. at : 型リストのI番目 ここからはめんどくさいからtuple版のみ template <int I, typename Arg> struct at; template <int I, typename Head, typename... Tail> struct at<I, tuple<Head, Tail...>> { typedef typename at<I - 1, tuple<Tail...>>::type type; }; template <class Head, typename... Tail> struct at<0, tuple<Head, Tail...>> { typedef Head type; }; at<1, tuple<int, long, char>>::type → long
  • 8. concat : 型リストの連結 template <class Seq1, class Seq2> struct concat; template <class... Seq1, class... Seq2> struct concat<tuple<Seq1...>, tuple<Seq2...>> { typedef tuple<Seq1..., Seq2...> type; }; concat<tuple<int, double>, tuple<long, char>>::type → tuple<int, double, long, char>
  • 9. reverse : 型リストを逆順にする 型の長さ分だけ再帰して、先頭を後ろに追加していく template <int N, class Seq> struct reverse_impl; template <int N, class Head, class... Tail> struct reverse_impl<N, tuple<Head, Tail...>> { typedef typename concat<typename reverse_impl<N-1, tuple<Tail...>>::type, tuple<Head> >::type type; }; template <class... Seq> struct reverse_impl<0, tuple<Seq...>> { typedef tuple<Seq...> type; };
  • 10. reverse : 型リストを逆順にする template <class Seq> struct reverse; template <class... Seq> struct reverse<tuple<Seq...>> { typedef typename reverse_impl<sizeof...(Seq), tuple<Seq...>>::type type; }; reverse<tuple<int, double, long>>::type → tuple<long, double, int>
  • 11. replicate : TをN個含んだ型リストを作成 N個分だけ再帰してconcatで型を追加していく template <int N, class T> struct replicate { typedef typename concat<typename replicate<N-1, T>::type, tuple<T> >::type type; }; template <class T> struct replicate<0, T> { typedef tuple<> type; }; replicate<3, int>::type → tuple<int, int, int>
  • 12. take : 先頭N個の型を取得 template <int N, class Seq> struct take; template <int N, class Head, class... Tail> struct take<N, tuple<Head, Tail...>> { typedef typename concat<tuple<Head>, typename take<N-1, tuple<Tail...>>::type >::type type; }; template <class Head, class... Tail> struct take<1, tuple<Head, Tail...>> { typedef tuple<Head> type; }; template <class Head, class... Tail> struct take<0, tuple<Head, Tail...>> { typedef tuple<> type; }; take<3, tuple<int, double, long, char, void*>>::type → tuple<int, double, long>
  • 13. drop : 先頭N個を除外した型リストを取得 template <int N, class Seq> struct drop; template <int N, class Head, class... Tail> struct drop<N, tuple<Head, Tail...>> { typedef typename drop<N-1, tuple<Tail...>>::type type; }; template <class Head, class... Tail> struct drop<0, tuple<Head, Tail...>> { typedef tuple<Head, Tail...> type; }; drop<3, tuple<int, double, long, char, void*>>::type → tuple<char, void*>
  • 14. map : 型リストの全ての型にメタ関数を適用 mapはメタ関数をパラメータで受け取る高階メタ関数 メタ関数は、テンプレートテンプレートパラメータで受け取る template <template <class T> class F, class... Seq> struct map; template <template <class T> class F, class... Seq> struct map<F, tuple<Seq...>> { typedef tuple<typename F<Seq>::type...> type; }; template <class T> struct add_pointer { typedef T* type; }; map<add_pointer, tuple<int, double, long>>::type → tuple<int*, double*, long*>
  • 15. filter : 条件抽出(1) まず、条件を満たす場合のみ型リストに型を追加するメタ関数を用意する template <bool B, class T, class Seq> struct add_if_c; template <class T, class... Seq> struct add_if_c<true, T, tuple<Seq...>> { typedef tuple<Seq..., T> type; }; template <class T, class... Seq> struct add_if_c<false, T, tuple<Seq...>> { typedef tuple<Seq...> type; }; template <template <class> class P, class T, class... Seq> struct add_if; template <template <class> class P, class T, class... Seq> struct add_if<P, T, tuple<Seq...>> : public add_if_c<P<T>::value, T, tuple<Seq...>> {};
  • 16. filter : 条件抽出(2) add_ifを使って、述語を満たす型のみの型リストを作成 template <template <class T> class P, class Seq1, class Seq2> struct filter_impl; template <template <class T> class P, class... Seq, class Head, class... Tail> struct filter_impl<P, tuple<Seq...>, tuple<Head, Tail...>> { typedef typename filter_impl<P, typename add_if<P, Head, tuple<Seq...>>::type, tuple<Tail...>>::type type; }; template <template <class T> class P, class... Seq> struct filter_impl<P, tuple<Seq...>, tuple<>> { typedef tuple<Seq...> type; }; template <template <class T> class P, class... Seq> struct filter; template <template <class T> class P, class... Seq> struct filter<P, tuple<Seq...>> { typedef typename filter_impl<P, tuple<>, tuple<Seq...>>::type type; }; filter<is_integral, tuple<int, double, long>>::type → tuple<int, long>
  • 17. take_while : 条件を満たす先頭部分を取り出す template <template <class T> class P, class Seq1, class Seq2> struct take_while_impl; template <template <class T> class P, class... Seq, class Head, class... Tail> struct take_while_impl<P, tuple<Seq...>, tuple<Head, Tail...>> { typedef typename if_c<P<Head>::value, typename take_while_impl<P, typename concat<tuple<Seq...>, tuple<Head>>::type, tuple<Tail...> >::type, tuple<Seq...> >::type type; }; template <template <class T> class P, class... Seq> struct take_while_impl<P, tuple<Seq...>, tuple<>> { typedef tuple<Seq...> type; }; template <template <class T> class P, class Seq> struct take_while; template <template <class T> class P, class... Seq> struct take_while<P, tuple<Seq...>> { typedef typename take_while_impl<P, tuple<>, tuple<Seq...>>::type type; }; take_while<is_integral, tuple<int, long, char, double>>::type → tuple<int, long, char>
  • 18. drop_while : 条件を満たす先頭部分を取り出す template <template <class T> class P, class Seq> struct drop_while; template <template <class T> class P, class Head, class... Tail> struct drop_while<P, tuple<Head, Tail...>> { typedef typename if_c<P<Head>::value, // trueだったら typename drop_while<P, tuple<Tail...>>::type, // 無視する tuple<Head, Tail...> >::type type; }; template <template <class T> class P> struct drop_while<P, tuple<>> { typedef tuple<> type; }; drop_while<is_integral, tuple<int, long, char, double>>::type → tuple<double>
  • 19. all : 型リストの要素全てが述語を満たすか 型リストの全ての型が述語を満たせばtrue それ以外はfalseを返す template <template <class T> class P, class Seq> struct all; template <template <class T> class P, class Head, class... Tail> struct all<P, tuple<Head, Tail...>> { static const bool value = !P<Head>::value ? false : all<P, tuple<Tail...>>::value; }; template <template <class T> class P> struct all<P, tuple<>> { static const bool value = true; }; all<is_integral, tuple<int, long, char>>::value → true all<is_integral, tuple<int, double, char>>::value → false
  • 20. any :型リストに述語を満たす型があるか 型リストのいずれかの型が述語を満たせばtrue それ以外はfalseを返す template <template <class T> class P, class Seq> struct any; template <template <class T> class P, class Head, class... Tail> struct any<P, tuple<Head, Tail...>> { static const bool value = P<Head>::value ? true : any<P, tuple<Tail...>>::value; }; template <template <class T> class P> struct any<P, tuple<>> { static const bool value = false; }; any<is_integral, tuple<int, long, char>>::value → true any<is_integral, tuple<float, int, void*>>::value → true any<is_integral, tuple<float, double, void*>>::value → false