LeechCraft  0.6.70-13729-g7046a9d2a7
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 LC
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  template<typename Type, template<typename...> class List, typename... Args>
116  constexpr bool HasType (List<Args...>)
117  {
118  return (std::is_same_v<Type, Args> || ...);
119  }
120 
121  namespace detail
122  {
123  template<template<typename> class, typename, typename = void>
124  struct Filter;
125  }
126 
127  template<template<typename> class Pred, typename List>
128  using Filter_t = typename detail::Filter<Pred, List>::Result_t;
129 
130  namespace detail
131  {
132  template<template<typename> class Pred, template<typename...> class List, typename Head, typename... Tail>
133  struct Filter<Pred, List<Head, Tail...>, std::enable_if_t<Pred<Head>::value>>
134  {
135  using Result_t = decltype (Concat (List<Head> {}, Filter_t<Pred, List<Tail...>> {}));
136  };
137 
138  template<template<typename> class Pred, template<typename...> class List, typename Head, typename... Tail>
139  struct Filter<Pred, List<Head, Tail...>, std::enable_if_t<!Pred<Head>::value>>
140  {
141  using Result_t = Filter_t<Pred, List<Tail...>>;
142  };
143 
144  template<template<typename> class Pred, template<typename...> class List>
145  struct Filter<Pred, List<>>
146  {
147  using Result_t = List<>;
148  };
149  }
150 
151  template<typename T>
152  struct AsTypelist;
153 
154  template<template<typename...> class OtherList, typename... Args>
155  struct AsTypelist<OtherList<Args...>>
156  {
157  using Result_t = Typelist<Args...>;
158  };
159 
160  template<typename T>
162 
163  template<typename F, typename G, typename Def, typename Head, typename... Args>
165  {
166  if (f (Head {}))
167  return g (Head {});
168 
169  if constexpr (sizeof... (Args) > 0)
170  return FirstMatching (f, g, def, Util::Typelist<Args...> {});
171  else
172  return def ();
173  }
174 
175  namespace detail
176  {
177  template<template<typename> class Name, typename Def, typename... Args>
178  struct Find;
179 
180  template<template<typename> class Name, typename Def, typename T, typename... Rest>
181  struct Find<Name, Def, T, Rest...> : Find<Name, Def, Rest...> {};
182 
183  template<template<typename> class Name, typename Def, typename T, typename... Rest>
184  struct Find<Name, Def, Name<T>, Rest...>
185  {
186  using type = T;
187  };
188 
189  template<template<typename> class Name, typename Def>
190  struct Find<Name, Def>
191  {
192  using type = Def;
193  };
194  }
195 
196  template<template<typename> class Name, typename Def, typename... Args>
197  using Find = typename detail::Find<Name, Def, Args...>::type;
198 }
199 }
constexpr List Reverse(List<>)
Definition: typelist.h:89
Container< T > Concat(const Container< Container< T >> &containers)
Definition: prelude.h:186
List< Head >
Definition: typelist.h:95
STL namespace.
Container< T > Filter(const Container< T > &c, F f)
Definition: prelude.h:176
constexpr detail::ExprTree< detail::ExprType::LeafStaticPlaceholder, detail::MemberPtrs< Ptr > > f
Definition: oral.h:955
decltype(Concat(List< Head > {}, Filter_t< Pred, List< Tail... > > {})) Result_t
Definition: typelist.h:135
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
constexpr List< T... > Tail(List< H, T... >)
Definition: typelist.h:56
typename detail::Find< Name, Def, Args... >::type Find
Definition: typelist.h:197
typename Head< List >::Head_t Head_t
Definition: typelist.h:53
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:161
Definition: constants.h:35
auto FirstMatching(F f, G g, Def def, Util::Typelist< Head, Args... >)
Definition: typelist.h:164