LeechCraft  0.6.70-13605-g8cd066ad6a
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>
161  using AsTypelist_t = typename AsTypelist<T>::Result_t;
162 
163  template<typename F, typename G, typename Def, typename Head, typename... Args>
164  auto FirstMatching (F f, G g, Def def, Util::Typelist<Head, 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 }
LC::Util::Reverse
constexpr List Reverse(List<>)
Definition: typelist.h:140
LC::Util::Concat
Container< T > Concat(const Container< Container< T >> &containers)
Definition: prelude.h:185
LC::Util::List< Head >
List< Head >
Definition: typelist.h:146
LC::Util::detail::DropImpl::Result_t
typename DropImpl< N - 1, decltype(Tail(List {}))>::Result_t Result_t
Definition: typelist.h:117
LC::Util::XDG::Type
Type
Describes the various types of XDG .desktop files.
Definition: itemtypes.h:47
LC::Util::Find
typename detail::Find< Name, Def, Args... >::type Find
Definition: typelist.h:248
LC::Util::Filter
Container< T > Filter(const Container< T > &c, F f)
Definition: prelude.h:175
LC::Util::detail::Find
Definition: typelist.h:229
LC::Util::Head_t
typename Head< List >::Head_t Head_t
Definition: typelist.h:104
LC::Util::Tail
constexpr List< T... > Tail(List< H, T... >)
Definition: typelist.h:107
LC::Util::Drop
constexpr detail::DropImpl< N, List< Args... > >::Result_t Drop(List< Args... >)
Definition: typelist.h:128
LC::Util::AsTypelist_t
typename AsTypelist< T >::Result_t AsTypelist_t
Definition: typelist.h:212
LC
Definition: constants.h:34
LC::Util::oral::sph::f
constexpr detail::ExprTree< detail::ExprType::LeafStaticPlaceholder, detail::MemberPtrs< Ptr > > f
Definition: oral.h:1037
LC::Util::FirstMatching
auto FirstMatching(F f, G g, Def def, Util::Typelist< Head, Args... >)
Definition: typelist.h:215
LC::Util::Head
Definition: typelist.h:95