OmniSciDB  5ade3759e0
ExperimentalTypeUtilities.h
Go to the documentation of this file.
1 /*
2  * Copyright 2018 MapD Technologies, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef EXPERIMENTALTYPEUTILITIES_H
18 #define EXPERIMENTALTYPEUTILITIES_H
19 #ifndef __CUDACC__
20 
21 #include <boost/optional.hpp>
22 #include <iostream>
23 #include <tuple>
24 #include <utility>
25 
26 #include "ConstExprLib.h"
27 #include "sqltypes.h"
28 
29 #include "SQLTypeUtilities.h"
30 
31 namespace Experimental {
32 
35 
37 
38 template <typename T>
40  static auto getType(T const& t) { return t; }
41 };
42 
43 template <MetaTypeClassifications T>
45  template <typename SQL_TYPE_INFO>
46  static auto isTargetClass(SQL_TYPE_INFO const& s) {
47  return false;
48  }
49 };
50 
51 template <>
53  template <typename SQL_TYPE_INFO>
54  static auto isTargetClass(SQL_TYPE_INFO const& s) {
55  return s.is_geometry();
56  }
57 };
58 
59 template <>
61  template <typename SQL_TYPE_INFO>
62  static auto isTargetClass(SQL_TYPE_INFO const& s) {
63  return s.is_string();
64  }
65 };
66 
67 template <>
69  template <typename SQL_TYPE_INFO>
70  static auto isTargetClass(SQL_TYPE_INFO const& s) {
71  return s.is_array();
72  }
73 };
74 
75 template <>
76 struct MetaTypeClassDeterminant<Bucketizable> {
77  template <typename SQL_TYPE_INFO>
78  static auto isTargetClass(SQL_TYPE_INFO const& s) {
79  return is_member_of_typeset<kDATE>(s);
80  }
81 };
82 
83 template <>
85  static auto getType(SQLTypeInfo const& s) { return s.get_type(); }
86 };
87 
88 template <typename T, T VALUE>
89 struct MetaType {
90  using ResolvedType = T;
91  static T const resolved_value = VALUE;
92 };
93 
94 template <MetaTypeClassifications T>
95 struct MetaTypeClass {
96  static MetaTypeClassifications const sql_type_class = T;
97 };
98 
99 template <typename T>
100 using MetaTypeOptional = boost::optional<T>; // Switch after C++17
101 
104 
105 template <typename T, T VALUE>
107 
108 template <MetaTypeClassifications T>
110 
111 template <typename T, T... VALUES_PACK>
113  public CapturedMetaTypeOptional<T, VALUES_PACK>... {};
114 
115 template <MetaTypeClassifications... CLASSIFICATIONS_PACK>
117  public CapturedMetaTypeClassOptional<CLASSIFICATIONS_PACK>... {};
118 
119 template <typename T, T... VALUES_PACK>
121  public:
122  using ResolvedType = T;
123  using MetaTypeContainer = MetaTypeAny<ResolvedType, VALUES_PACK...>;
124 
125  template <typename SOURCE_TYPE>
126  static auto getMetaType(SOURCE_TYPE&& source_type) {
127  MetaTypeContainer return_value;
128  resolveType<VALUES_PACK...>(return_value,
130  return return_value;
131  }
132 
133  private:
134  template <ResolvedType VALUE>
135  static auto resolveType(MetaTypeContainer& return_value,
136  ResolvedType const switch_value) {
137  if (switch_value == VALUE) {
138  static_cast<CapturedMetaTypeOptional<ResolvedType, VALUE>&>(return_value) =
140  }
141  static_cast<UncapturedMetaTypeOptional&>(return_value) = UncapturedMetaType();
142  }
143 
144  template <ResolvedType FIRST_VALUE,
145  ResolvedType SECOND_VALUE,
146  ResolvedType... REMAINING_VALUES>
147  static auto resolveType(MetaTypeContainer& return_value,
148  ResolvedType const switch_value) {
149  if (switch_value == FIRST_VALUE) {
150  static_cast<CapturedMetaTypeOptional<ResolvedType, FIRST_VALUE>&>(return_value) =
152  return;
153  }
154  resolveType<SECOND_VALUE, REMAINING_VALUES...>(return_value, switch_value);
155  }
156 };
157 
158 template <MetaTypeClassifications... CLASSIFICATIONS_PACK>
160  public:
161  using MetaTypeClassContainer = MetaTypeClassAny<CLASSIFICATIONS_PACK...>;
162 
163  template <typename SQL_TYPE_INFO>
164  static auto getMetaTypeClass(SQL_TYPE_INFO const& sql_type_info)
166  MetaTypeClassContainer return_value;
167  resolveClassification<SQL_TYPE_INFO, CLASSIFICATIONS_PACK...>(return_value,
168  sql_type_info);
169  return return_value;
170  }
171 
172  private:
173  template <typename SQL_TYPE_INFO, MetaTypeClassifications FIRST_TYPE>
175  SQL_TYPE_INFO const& sql_type_info) {
177  static_cast<CapturedMetaTypeClassOptional<FIRST_TYPE>&>(return_value) =
179  return;
180  }
181  static_cast<UncapturedMetaTypeClassOptional&>(return_value) =
183  }
184 
185  template <typename SQL_TYPE_INFO,
186  MetaTypeClassifications FIRST_TYPE,
187  MetaTypeClassifications SECOND_TYPE,
188  MetaTypeClassifications... REMAINING_TYPES>
190  SQL_TYPE_INFO const& sql_type_info) {
192  static_cast<CapturedMetaTypeClassOptional<FIRST_TYPE>>(return_value) =
194  return;
195  }
196  resolveClassification<SQL_TYPE_INFO, SECOND_TYPE, REMAINING_TYPES...>(return_value,
197  sql_type_info);
198  }
199 };
200 
201 inline namespace Cpp14 {
202 struct Applicator {
203  template <class FUNCTION_TYPE, class TUPLE_TYPE, std::size_t... I>
204  decltype(auto) internalApplyImpl(FUNCTION_TYPE&& f,
205  TUPLE_TYPE&& t,
206  std::index_sequence<I...>) {
207  return f(std::get<I>(std::forward<TUPLE_TYPE>(t))...);
208  }
209 
210  template <class FUNCTION_TYPE, class TUPLE_TYPE>
211  decltype(auto) internalApply(FUNCTION_TYPE&& f, TUPLE_TYPE&& t) {
212  return internalApplyImpl(
213  std::forward<FUNCTION_TYPE>(f),
214  std::forward<TUPLE_TYPE>(t),
215  std::make_index_sequence<
216  std::tuple_size<std::remove_reference_t<TUPLE_TYPE>>::value>{});
217  }
218 };
219 
220 template <template <class> class SPECIALIZED_HANDLER,
221  typename T,
222  T... HANDLED_VALUES_PACK>
223 class MetaTypeHandler : protected Applicator {
224  public:
225  using ResolvedType = T;
226  static constexpr std::size_t handled_type_count = sizeof...(HANDLED_VALUES_PACK);
227 
228  template <typename META_TYPE, typename... ARG_PACK>
229  decltype(auto) operator()(META_TYPE const& meta_type, ARG_PACK&&... args) {
230  using ArgumentPackaging = decltype(std::forward_as_tuple(args...));
231  return handleMetaType<META_TYPE, ArgumentPackaging, HANDLED_VALUES_PACK...>(
232  meta_type, std::forward_as_tuple(args...));
233  }
234 
235  private:
236  template <typename META_TYPE, typename ARG_PACKAGING, ResolvedType VALUE>
237  decltype(auto) handleMetaType(META_TYPE const& meta_type,
238  ARG_PACKAGING&& arg_packaging) {
239  using InspectionValue = MetaType<ResolvedType, VALUE>;
240  using CastAssistType =
242 
243  auto const& lhs_ref = static_cast<CastAssistType const&>(meta_type);
244  if (!lhs_ref) {
245  return internalApply(SPECIALIZED_HANDLER<UncapturedMetaType>(), arg_packaging);
246  }
247  return internalApply(SPECIALIZED_HANDLER<InspectionValue>(), arg_packaging);
248  };
249 
250  template <typename META_TYPE,
251  typename ARG_PACKAGING,
253  ResolvedType SECOND_VALUE,
254  ResolvedType... REMAINING_VALUES>
255  decltype(auto) handleMetaType(META_TYPE const& meta_type,
256  ARG_PACKAGING&& arg_packaging) {
257  using InspectionValue = MetaType<ResolvedType, FIRST_VALUE>;
258  using CastAssistType =
260 
261  auto const& lhs_ref = static_cast<CastAssistType const&>(meta_type);
262  if (!lhs_ref) {
263  return handleMetaType<META_TYPE, ARG_PACKAGING, SECOND_VALUE, REMAINING_VALUES...>(
264  meta_type, std::forward<ARG_PACKAGING&&>(arg_packaging));
265  }
266  return internalApply(SPECIALIZED_HANDLER<InspectionValue>(), arg_packaging);
267  };
268 };
269 
270 template <template <class> class SPECIALIZED_HANDLER,
271  MetaTypeClassifications... HANDLED_TYPE_CLASSES_PACK>
272 class MetaTypeClassHandler : protected Applicator {
273  public:
274  using TypeList = std::tuple<MetaTypeClass<HANDLED_TYPE_CLASSES_PACK>...>;
275  static constexpr std::size_t handled_type_count = sizeof...(HANDLED_TYPE_CLASSES_PACK);
276 
277  template <typename META_TYPE_CLASS, typename... ARG_PACK>
278  decltype(auto) operator()(META_TYPE_CLASS& meta_type_class, ARG_PACK&&... args) {
279  using ArgumentPackaging = decltype(std::forward_as_tuple(args...));
280  return handleMetaTypeClass<META_TYPE_CLASS,
281  ArgumentPackaging,
282  HANDLED_TYPE_CLASSES_PACK...>(
283  meta_type_class, std::forward_as_tuple(args...));
284  }
285 
286  private:
287  template <typename META_TYPE_CLASS,
288  typename ARG_PACKAGING,
289  MetaTypeClassifications HANDLED_TYPE>
290  decltype(auto) handleMetaTypeClass(META_TYPE_CLASS& meta_type_class,
291  ARG_PACKAGING&& arg_packaging) {
292  using InspectionClass = MetaTypeClass<HANDLED_TYPE>;
293  using CastAssistClass =
295 
296  auto& lhs_ref = static_cast<CastAssistClass&>(meta_type_class);
297  if (!lhs_ref) {
298  return internalApply(SPECIALIZED_HANDLER<UncapturedMetaTypeClassOptional>(),
299  arg_packaging);
300  }
301  return internalApply(SPECIALIZED_HANDLER<InspectionClass>(), arg_packaging);
302  }
303 
304  template <typename META_TYPE_CLASS,
305  typename ARG_PACKAGING,
306  MetaTypeClassifications FIRST_HANDLED_TYPE,
307  MetaTypeClassifications SECOND_HANDLED_TYPE,
308  MetaTypeClassifications... REMAINING_TYPES>
309  decltype(auto) handleMetaTypeClass(META_TYPE_CLASS& meta_type_class,
310  ARG_PACKAGING&& arg_packaging) {
311  using InspectionClass = MetaTypeClass<FIRST_HANDLED_TYPE>;
312  using CastAssistClass =
314 
315  auto& lhs_ref = static_cast<CastAssistClass&>(meta_type_class);
316  if (!lhs_ref) {
317  return handleMetaTypeClass<META_TYPE_CLASS,
318  ARG_PACKAGING,
319  SECOND_HANDLED_TYPE,
320  REMAINING_TYPES...>(
321  meta_type_class, std::forward<ARG_PACKAGING>(arg_packaging));
322  }
323  return internalApply(SPECIALIZED_HANDLER<InspectionClass>(), arg_packaging);
324  }
325 };
326 
327 } // namespace Cpp14
328 
329 using GeoMetaTypeFactory =
332  kNULLT,
333  kBOOLEAN,
334  kCHAR,
335  kVARCHAR,
336  kNUMERIC,
337  kDECIMAL,
338  kINT,
339  kSMALLINT,
340  kFLOAT,
341  kDOUBLE,
342  kTIME,
343  kTIMESTAMP,
344  kBIGINT,
345  kTEXT,
346  kDATE,
347  kARRAY,
350  kPOINT,
351  kLINESTRING,
352  kPOLYGON,
354  kTINYINT,
355  kGEOMETRY,
356  kGEOGRAPHY,
358 
363 
364 template <template <class> class SPECIALIZED_HANDLER>
365 using GeoMetaTypeHandler = MetaTypeHandler<SPECIALIZED_HANDLER,
366  SQLTypes,
367  kPOINT,
368  kLINESTRING,
369  kPOLYGON,
370  kMULTIPOLYGON>;
371 
372 template <template <class> class SPECIALIZED_HANDLER>
373 using FullMetaTypeHandler = MetaTypeHandler<SPECIALIZED_HANDLER,
374  SQLTypes,
375  kNULLT,
376  kBOOLEAN,
377  kCHAR,
378  kVARCHAR,
379  kNUMERIC,
380  kDECIMAL,
381  kINT,
382  kSMALLINT,
383  kFLOAT,
384  kDOUBLE,
385  kTIME,
386  kTIMESTAMP,
387  kBIGINT,
388  kTEXT,
389  kDATE,
390  kARRAY,
393  kPOINT,
394  kLINESTRING,
395  kPOLYGON,
397  kTINYINT,
398  kGEOMETRY,
399  kGEOGRAPHY,
401 
402 template <template <class> class SPECIALIZED_HANDLER>
403 using GeoVsNonGeoClassHandler = MetaTypeClassHandler<SPECIALIZED_HANDLER, Geometry>;
404 
405 template <template <class> class SPECIALIZED_HANDLER>
407  MetaTypeClassHandler<SPECIALIZED_HANDLER, Geometry, Array, String, Bucketizable>;
408 
409 template <template <class> class SPECIALIZED_HANDLER,
410  typename SQL_TYPE_INFO,
411  typename... HANDLER_ARGS>
412 decltype(auto) FullMetaTypeSwitch(SQL_TYPE_INFO const& ti,
413  HANDLER_ARGS&&... handler_args) {
414  auto ti_meta_type = FullMetaTypeFactory::getMetaType(ti.get_type());
415  auto meta_type_handler = FullMetaTypeHandler<SPECIALIZED_HANDLER>();
416  return meta_type_handler(ti_meta_type, std::forward<HANDLER_ARGS>(handler_args)...);
417 }
418 
419 template <template <class> class SPECIALIZED_HANDLER,
420  typename SQL_TYPE_INFO,
421  typename... HANDLER_ARGS>
422 decltype(auto) FullMetaTypeClassSwitch(SQL_TYPE_INFO const& ti,
423  HANDLER_ARGS&&... handler_args) {
424  auto ti_meta_type_class = FullMetaTypeClassFactory::getMetaTypeClass(ti);
425  auto meta_type_class_handler = FullMetaTypeClassHandler<SPECIALIZED_HANDLER>();
426  return meta_type_class_handler(ti_meta_type_class,
427  std::forward<HANDLER_ARGS>(handler_args)...);
428 }
429 
430 } // namespace Experimental
431 
432 #endif
433 #endif
static auto resolveType(MetaTypeContainer &return_value, ResolvedType const switch_value)
static auto getMetaTypeClass(SQL_TYPE_INFO const &sql_type_info) -> MetaTypeClassContainer
Definition: sqltypes.h:51
SQLTypes
Definition: sqltypes.h:40
MetaTypeHandler< SPECIALIZED_HANDLER, SQLTypes, kPOINT, kLINESTRING, kPOLYGON, kMULTIPOLYGON > GeoMetaTypeHandler
MetaTypeOptional< UncapturedMetaTypeClass > UncapturedMetaTypeClassOptional
static auto getMetaType(SOURCE_TYPE &&source_type)
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:323
Constants for Builtin SQL Types supported by MapD.
boost::optional< T > MetaTypeOptional
MetaTypeOptional< UncapturedMetaType > UncapturedMetaTypeOptional
static auto isTargetClass(SQL_TYPE_INFO const &s)
static auto resolveType(MetaTypeContainer &return_value, ResolvedType const switch_value)
MetaTypeOptional< MetaType< T, VALUE > > CapturedMetaTypeOptional
MetaTypeOptional< MetaTypeClass< T > > CapturedMetaTypeClassOptional
decltype(auto) FullMetaTypeClassSwitch(SQL_TYPE_INFO const &ti, HANDLER_ARGS &&... handler_args)
Definition: sqltypes.h:54
Definition: sqltypes.h:55
std::tuple< MetaTypeClass< HANDLED_TYPE_CLASSES_PACK >... > TypeList
MetaTypeHandler< SPECIALIZED_HANDLER, SQLTypes, kNULLT, kBOOLEAN, kCHAR, kVARCHAR, kNUMERIC, kDECIMAL, kINT, kSMALLINT, kFLOAT, kDOUBLE, kTIME, kTIMESTAMP, kBIGINT, kTEXT, kDATE, kARRAY, kINTERVAL_DAY_TIME, kINTERVAL_YEAR_MONTH, kPOINT, kLINESTRING, kPOLYGON, kMULTIPOLYGON, kTINYINT, kGEOMETRY, kGEOGRAPHY, kEVAL_CONTEXT_TYPE > FullMetaTypeHandler
decltype(auto) FullMetaTypeSwitch(SQL_TYPE_INFO const &ti, HANDLER_ARGS &&... handler_args)
MetaTypeClassHandler< SPECIALIZED_HANDLER, Geometry, Array, String, Bucketizable > FullMetaTypeClassHandler
Definition: sqltypes.h:43
static void resolveClassification(MetaTypeClassContainer &return_value, SQL_TYPE_INFO const &sql_type_info)
MetaTypeClassHandler< SPECIALIZED_HANDLER, Geometry > GeoVsNonGeoClassHandler
Definition: sqltypes.h:47
static void resolveClassification(MetaTypeClassContainer &return_value, SQL_TYPE_INFO const &sql_type_info)