OGLplus (0.52.0) a C++ wrapper for OpenGL

one_of.hpp
Go to the documentation of this file.
1 
12 #pragma once
13 #ifndef OGLPLUS_ONE_OF_1107121519_HPP
14 #define OGLPLUS_ONE_OF_1107121519_HPP
15 
16 #include <oglplus/config/compiler.hpp>
17 
18 #include <type_traits>
19 #include <tuple>
20 
21 namespace oglplus {
22 namespace aux {
23 
24 template <typename Common, typename T>
25 class OneOfBase
26 {
27  static_assert(
28  !std::is_same<T, void>::value,
29  "The passed value has not one of the allowed types!"
30  );
31 protected:
32  static inline Common Accept(T value)
33  {
34  return Common(value);
35  }
36 };
37 
38 } // namespace aux
39 
40 
41 #if OGLPLUS_DOCUMENTATION_ONLY
42 
59 template <typename Common, typename Variants>
60 class OneOf
61 {
62 public:
64  operator Common(void) const;
65 };
66 #else
67 template <typename Common, typename TypeList>
68 class OneOf;
69 #endif
70 
71 // Specialization for the common case of two variants
72 template <typename Common, typename V1, typename V2>
73 class OneOf<Common, std::tuple<V1, V2>>
74 {
75 private:
76  Common _value;
77 public:
78  OneOf(V1 value)
79  : _value(Common(value))
80  { }
81 
82  OneOf(V2 value)
83  : _value(Common(value))
84  { }
85 
86  template <typename T>
87  OneOf(
88  T value,
89  typename std::enable_if<
90  std::is_convertible<T, V1>::value
91  >::type* = nullptr
92  ): _value(Common(V1(value)))
93  { }
94 
95  template <typename T>
96  OneOf(
97  T value,
98  typename std::enable_if<
99  std::is_convertible<T, V2>::value
100  >::type* = nullptr
101  ): _value(Common(V2(value)))
102  { }
103 
104  OGLPLUS_EXPLICIT operator Common (void) const
105  OGLPLUS_NOEXCEPT(true)
106  {
107  return _value;
108  }
109 };
110 
111 // Specialization for the common case of three variants
112 template <typename Common, typename V1, typename V2, typename V3>
113 class OneOf<Common, std::tuple<V1, V2, V3>>
114 {
115 private:
116  Common _value;
117 public:
118  OneOf(V1 value)
119  : _value(Common(value))
120  { }
121 
122  OneOf(V2 value)
123  : _value(Common(value))
124  { }
125 
126  OneOf(V3 value)
127  : _value(Common(value))
128  { }
129 
130  template <typename T>
131  OneOf(
132  T value,
133  typename std::enable_if<
134  std::is_convertible<T, V1>::value
135  >::type* = nullptr
136  ): _value(Common(V1(value)))
137  { }
138 
139  template <typename T>
140  OneOf(
141  T value,
142  typename std::enable_if<
143  std::is_convertible<T, V2>::value
144  >::type* = nullptr
145  ): _value(Common(V2(value)))
146  { }
147 
148  template <typename T>
149  OneOf(
150  T value,
151  typename std::enable_if<
152  std::is_convertible<T, V3>::value
153  >::type* = nullptr
154  ): _value(Common(V3(value)))
155  { }
156 
157  OGLPLUS_EXPLICIT operator Common (void) const
158  OGLPLUS_NOEXCEPT(true)
159  {
160  return _value;
161  }
162 };
163 
164 #if !OGLPLUS_NO_VARIADIC_TEMPLATES
165 template <typename Common, typename ... Variants>
166 class OneOf<Common, std::tuple<Variants...>>
167  : public aux::OneOfBase<Common, Variants>...
168 {
169 private:
170  Common _value;
171 
172  template <typename T>
173  struct is_one_of
174  : std::is_convertible<
175  OneOf,
176  aux::OneOfBase<Common, T>
177  >
178  { };
179 
180  template <typename T, typename V, typename ... Vi>
181  static V _do_find_one_of(std::true_type);
182 
183  template <typename T, typename V>
184  static void _do_find_one_of(std::false_type);
185 
186  template <typename T, typename V, typename ... Vi>
187  static auto _find_one_of(void) ->
188  decltype(_do_find_one_of<T, V, Vi...>(std::is_convertible<T, V>()));
189 
190  template <typename T, typename V, typename V1, typename ... Vi>
191  static auto _do_find_one_of(std::false_type) ->
192  decltype(_find_one_of<T, V1, Vi...>());
193 
194  template <typename T>
195  struct find
196  {
197  typedef decltype(_find_one_of<T, Variants...>()) type;
198  };
199 public:
200  template <typename T>
201  OneOf(
202  T value,
203  typename std::enable_if<is_one_of<T>::value>::type* = nullptr
204  ): _value(aux::OneOfBase<Common, T>::Accept(value))
205  { }
206 
207  template <typename T>
208  OneOf(
209  T value,
210  typename std::enable_if<!is_one_of<T>::value>::type* = nullptr
211  ): _value(aux::OneOfBase<Common, typename find<T>::type>::Accept(value))
212  { }
213 
214  OGLPLUS_EXPLICIT operator Common (void) const
215  OGLPLUS_NOEXCEPT(true)
216  {
217  return _value;
218  }
219 };
220 #endif // !OGLPLUS_NO_VARIADIC_TEMPLATES
221 
222 } // namespace oglplus
223 
224 #endif // include guard
Stores a value having one of the listed types in a common representation.
Definition: one_of.hpp:60

Copyright © 2010-2014 Matúš Chochlík, University of Žilina, Žilina, Slovakia.
<matus.chochlik -at- fri.uniza.sk>
<chochlik -at -gmail.com>
Documentation generated on Mon Sep 22 2014 by Doxygen (version 1.8.6).