LeechCraft  0.6.70-10870-g558588d6ec
Modular cross-platform feature rich live environment.
typelist.h
Go to the documentation of this file.
1 /**********************************************************************
2  * LeechCraft - modular cross-platform feature rich internet client.
3  * Copyright (C) 2006-2014 Georg Rudoy
4  *
5  * Boost Software License - Version 1.0 - August 17th, 2003
6  *
7  * Permission is hereby granted, free of charge, to any person or organization
8  * obtaining a copy of the software and accompanying documentation covered by
9  * this license (the "Software") to use, reproduce, display, distribute,
10  * execute, and transmit the Software, and to prepare derivative works of the
11  * Software, and to permit third-parties to whom the Software is furnished to
12  * do so, all subject to the following:
13  *
14  * The copyright notices in the Software and this entire statement, including
15  * the above license grant, this restriction and the following disclaimer,
16  * must be included in all copies of the Software, in whole or in part, and
17  * all derivative works of the Software, unless such copies or derivative
18  * works are solely in the form of machine-executable object code generated by
19  * a source language processor.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
24  * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
25  * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
26  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27  * DEALINGS IN THE SOFTWARE.
28  **********************************************************************/
29 
30 #pragma once
31 
32 #include <tuple>
33 
34 namespace LeechCraft
35 {
36 namespace Util
37 {
38  template<typename...>
39  struct Typelist
40  {
41  };
42 
43  template<typename>
44  struct Head;
45 
46  template<template<typename...> class List, typename H, typename... T>
47  struct Head<List<H, T...>>
48  {
49  using Head_t = H;
50  };
51 
52  template<typename List>
53  using Head_t = typename Head<List>::Head_t;
54 
55  template<template<typename...> class List, typename H, typename... T>
56  constexpr List<T...> Tail (List<H, T...>)
57  {
58  return {};
59  }
60 
61  namespace detail
62  {
63  template<int N, typename List>
64  struct DropImpl
65  {
66  using Result_t = typename DropImpl<N - 1, decltype (Tail (List {}))>::Result_t;
67  };
68 
69  template<typename List>
70  struct DropImpl<0, List>
71  {
72  using Result_t = List;
73  };
74  }
75 
76  template<int N, template<typename...> class List, typename... Args>
77  constexpr typename detail::DropImpl<N, List<Args...>>::Result_t Drop (List<Args...>)
78  {
79  return {};
80  }
81 
82  template<template<typename...> class List, typename... Args1, typename... Args2>
83  constexpr List<Args1..., Args2...> Concat (List<Args1...>, List<Args2...>)
84  {
85  return {};
86  }
87 
88  template<template<typename...> class List>
89  constexpr List<> Reverse (List<>)
90  {
91  return {};
92  }
93 
94  template<template<typename...> class List, typename Head, typename... Tail>
95  constexpr auto Reverse (List<Head, Tail...>) -> decltype (Concat (Reverse (List<Tail...> {}), List<Head> {}))
96  {
97  return {};
98  }
99 
100  namespace detail
101  {
102  template<template<typename...> class List, typename Tuple, size_t... Is>
103  constexpr auto InitImpl (std::integer_sequence<size_t, Is...>)
104  {
105  return List<std::tuple_element_t<Is, Tuple>...> {};
106  }
107  }
108 
109  template<template<typename...> class List, typename... Args>
110  constexpr auto Init (List<Args...>)
111  {
112  return detail::InitImpl<List, std::tuple<Args...>> (std::make_index_sequence<sizeof... (Args) - 1> {});
113  }
114 
115  namespace detail
116  {
117  template<typename Type, template<typename...> class List, typename... Tail>
118  constexpr bool HasTypeImpl (List<Type, Tail...>, int)
119  {
120  return true;
121  }
122 
123  template<typename, template<typename...> class List>
124  constexpr bool HasTypeImpl (List<>, float)
125  {
126  return false;
127  }
128 
129  template<typename Type, template<typename...> class List, typename Head, typename... Tail>
130  constexpr bool HasTypeImpl (List<Head, Tail...>, float)
131  {
132  return HasTypeImpl<Type> (List<Tail...> {}, 0);
133  }
134  }
135 
136  template<typename Type, template<typename...> class List, typename... Args>
137  constexpr bool HasType (List<Args...> list)
138  {
139  return detail::HasTypeImpl<Type> (list, 0);
140  }
141 
142  namespace detail
143  {
144  template<template<typename> class, typename, typename = void>
145  struct Filter;
146  }
147 
148  template<template<typename> class Pred, typename List>
149  using Filter_t = typename detail::Filter<Pred, List>::Result_t;
150 
151  namespace detail
152  {
153  template<template<typename> class Pred, template<typename...> class List, typename Head, typename... Tail>
154  struct Filter<Pred, List<Head, Tail...>, std::enable_if_t<Pred<Head>::value>>
155  {
156  using Result_t = decltype (Concat (List<Head> {}, Filter_t<Pred, List<Tail...>> {}));
157  };
158 
159  template<template<typename> class Pred, template<typename...> class List, typename Head, typename... Tail>
160  struct Filter<Pred, List<Head, Tail...>, std::enable_if_t<!Pred<Head>::value>>
161  {
162  using Result_t = Filter_t<Pred, List<Tail...>>;
163  };
164 
165  template<template<typename> class Pred, template<typename...> class List>
166  struct Filter<Pred, List<>>
167  {
168  using Result_t = List<>;
169  };
170  }
171 
172  template<typename T>
173  struct AsTypelist;
174 
175  template<template<typename...> class OtherList, typename... Args>
176  struct AsTypelist<OtherList<Args...>>
177  {
178  using Result_t = Typelist<Args...>;
179  };
180 
181  template<typename T>
183 
184  template<typename F, typename G, typename Def, typename Head, typename... Args>
186  {
187  if (f (Head {}))
188  return g (Head {});
189 
190  if constexpr (sizeof... (Args) > 0)
191  return FirstMatching (f, g, def, Util::Typelist<Args...> {});
192  else
193  return def ();
194  }
195 }
196 }
constexpr List< T... > Tail(List< H, T... >)
Definition: typelist.h:56
constexpr detail::ExprTree< detail::ExprType::LeafStaticPlaceholder, detail::MemberPtrs< Ptr > > f
Definition: oral.h:931
auto FirstMatching(F f, G g, Def def, Util::Typelist< Head, Args... >)
Definition: typelist.h:185
constexpr List Reverse(List<>)
Definition: typelist.h:89
STL namespace.
typename Head< List >::Head_t Head_t
Definition: typelist.h:53
Container< T > Concat(const Container< Container< T >> &containers)
Definition: prelude.h:187
typename DropImpl< N - 1, decltype(Tail(List {}))>::Result_t Result_t
Definition: typelist.h:66
Type
Describes the various types of XDG .desktop files.
Definition: itemtypes.h:48
Container< T > Filter(const Container< T > &c, F f)
Definition: prelude.h:177
decltype(Concat(List< Head > {}, Filter_t< Pred, List< Tail... > > {})) Result_t
Definition: typelist.h:156
constexpr detail::DropImpl< N, List< Args... > >::Result_t Drop(List< Args... >)
Definition: typelist.h:77
typename AsTypelist< T >::Result_t AsTypelist_t
Definition: typelist.h:182