LeechCraft  0.6.70-15082-g543737046d
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  * Distributed under the Boost Software License, Version 1.0.
6  * (See accompanying file LICENSE or copy at https://www.boost.org/LICENSE_1_0.txt)
7  **********************************************************************/
8 
9 #pragma once
10 
11 #include <tuple>
12 
13 namespace LC
14 {
15 namespace Util
16 {
17  template<typename...>
18  struct Typelist
19  {
20  };
21 
22  template<typename>
23  struct Head;
24 
25  template<template<typename...> class List, typename H, typename... T>
26  struct Head<List<H, T...>>
27  {
28  using Head_t = H;
29  };
30 
31  template<typename List>
32  using Head_t = typename Head<List>::Head_t;
33 
34  template<template<typename...> class List, typename H, typename... T>
35  constexpr List<T...> Tail (List<H, T...>)
36  {
37  return {};
38  }
39 
40  namespace detail
41  {
42  template<int N, typename List>
43  struct DropImpl
44  {
45  using Result_t = typename DropImpl<N - 1, decltype (Tail (List {}))>::Result_t;
46  };
47 
48  template<typename List>
49  struct DropImpl<0, List>
50  {
51  using Result_t = List;
52  };
53  }
54 
55  template<int N, template<typename...> class List, typename... Args>
56  constexpr typename detail::DropImpl<N, List<Args...>>::Result_t Drop (List<Args...>)
57  {
58  return {};
59  }
60 
61  template<template<typename...> class List, typename... Args1, typename... Args2>
62  constexpr List<Args1..., Args2...> Concat (List<Args1...>, List<Args2...>)
63  {
64  return {};
65  }
66 
67  template<template<typename...> class List>
68  constexpr List<> Reverse (List<>)
69  {
70  return {};
71  }
72 
73  template<template<typename...> class List, typename Head, typename... Tail>
74  constexpr auto Reverse (List<Head, Tail...>) -> decltype (Concat (Reverse (List<Tail...> {}), List<Head> {}))
75  {
76  return {};
77  }
78 
79  namespace detail
80  {
81  template<template<typename...> class List, typename Tuple, size_t... Is>
82  constexpr auto InitImpl (std::integer_sequence<size_t, Is...>)
83  {
84  return List<std::tuple_element_t<Is, Tuple>...> {};
85  }
86  }
87 
88  template<template<typename...> class List, typename... Args>
89  constexpr auto Init (List<Args...>)
90  {
91  return detail::InitImpl<List, std::tuple<Args...>> (std::make_index_sequence<sizeof... (Args) - 1> {});
92  }
93 
94  template<typename Type, template<typename...> class List, typename... Args>
95  constexpr bool HasType (List<Args...>)
96  {
97  return (std::is_same_v<Type, Args> || ...);
98  }
99 
100  namespace detail
101  {
102  template<template<typename> class, typename, typename = void>
103  struct Filter;
104  }
105 
106  template<template<typename> class Pred, typename List>
107  using Filter_t = typename detail::Filter<Pred, List>::Result_t;
108 
109  namespace detail
110  {
111  template<template<typename> class Pred, template<typename...> class List, typename Head, typename... Tail>
112  struct Filter<Pred, List<Head, Tail...>, std::enable_if_t<Pred<Head>::value>>
113  {
114  using Result_t = decltype (Concat (List<Head> {}, Filter_t<Pred, List<Tail...>> {}));
115  };
116 
117  template<template<typename> class Pred, template<typename...> class List, typename Head, typename... Tail>
118  struct Filter<Pred, List<Head, Tail...>, std::enable_if_t<!Pred<Head>::value>>
119  {
120  using Result_t = Filter_t<Pred, List<Tail...>>;
121  };
122 
123  template<template<typename> class Pred, template<typename...> class List>
124  struct Filter<Pred, List<>>
125  {
126  using Result_t = List<>;
127  };
128  }
129 
130  template<typename T>
131  struct AsTypelist;
132 
133  template<template<typename...> class OtherList, typename... Args>
134  struct AsTypelist<OtherList<Args...>>
135  {
136  using Result_t = Typelist<Args...>;
137  };
138 
139  template<typename T>
140  using AsTypelist_t = typename AsTypelist<T>::Result_t;
141 
142  template<typename F, typename G, typename Def, typename Head, typename... Args>
144  {
145  if (f (Head {}))
146  return g (Head {});
147 
148  if constexpr (sizeof... (Args) > 0)
149  return FirstMatching (f, g, def, Util::Typelist<Args...> {});
150  else
151  return def ();
152  }
153 
154  namespace detail
155  {
156  template<template<typename> class Name, typename Def, typename... Args>
157  struct Find;
158 
159  template<template<typename> class Name, typename Def, typename T, typename... Rest>
160  struct Find<Name, Def, T, Rest...> : Find<Name, Def, Rest...> {};
161 
162  template<template<typename> class Name, typename Def, typename T, typename... Rest>
163  struct Find<Name, Def, Name<T>, Rest...>
164  {
165  using type = T;
166  };
167 
168  template<template<typename> class Name, typename Def>
169  struct Find<Name, Def>
170  {
171  using type = Def;
172  };
173  }
174 
175  template<template<typename> class Name, typename Def, typename... Args>
176  using Find = typename detail::Find<Name, Def, Args...>::type;
177 }
178 }
LC::Util::Reverse
constexpr List Reverse(List<>)
Definition: typelist.h:80
LC::Util::Concat
Container< T > Concat(const Container< Container< T >> &containers)
Definition: prelude.h:171
LC::Util::detail::Filter< Pred, List< Head, Tail... >, std::enable_if_t< Pred< Head >::value > >::Result_t
decltype(Concat(List< Head > {}, Filter_t< Pred, List< Tail... > > {})) Result_t
Definition: typelist.h:126
LC::Util::List< Head >
List< Head >
Definition: typelist.h:86
LC::Util::detail::DropImpl::Result_t
typename DropImpl< N - 1, decltype(Tail(List {}))>::Result_t Result_t
Definition: typelist.h:57
LC::Util::XDG::Type
Type
Describes the various types of XDG .desktop files.
Definition: itemtypes.h:23
LC::Util::Find
typename detail::Find< Name, Def, Args... >::type Find
Definition: typelist.h:188
LC::Util::Filter
Container< T > Filter(const Container< T > &c, F f)
Definition: prelude.h:161
LC::Util::Typelist
Definition: typelist.h:30
LC::Util::detail::Find
Definition: typelist.h:169
LC::Util::Head_t
typename Head< List >::Head_t Head_t
Definition: typelist.h:44
LC::Util::Tail
constexpr List< T... > Tail(List< H, T... >)
Definition: typelist.h:47
LC::Util::AsTypelist
Definition: typelist.h:143
LC::Util::Drop
constexpr detail::DropImpl< N, List< Args... > >::Result_t Drop(List< Args... >)
Definition: typelist.h:68
LC::Util::AsTypelist_t
typename AsTypelist< T >::Result_t AsTypelist_t
Definition: typelist.h:152
LC::Util::detail::DropImpl
Definition: typelist.h:55
LC::Util::detail::Find< Name, Def, Name< T >, Rest... >::type
T type
Definition: typelist.h:177
LC
Definition: constants.h:14
LC::Util::oral::sph::f
constexpr detail::ExprTree< detail::ExprType::LeafStaticPlaceholder, detail::MemberPtrs< Ptr > > f
Definition: oral.h:952
LC::Util::detail::Filter< Pred, List<> >::Result_t
List<> Result_t
Definition: typelist.h:138
LC::Util::FirstMatching
auto FirstMatching(F f, G g, Def def, Util::Typelist< Head, Args... >)
Definition: typelist.h:155
LC::Util::Head
Definition: typelist.h:35