traits.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019-2022, NVIDIA CORPORATION.
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 #pragma once
18 
19 #include <cudf/types.hpp>
23 
24 #include <cuda/std/type_traits>
25 
26 namespace cudf {
27 
34 template <typename...>
35 using void_t = void;
36 
48 #define CUDF_ENABLE_IF(...) std::enable_if_t<(__VA_ARGS__)>* = nullptr
49 
50 template <typename L, typename R>
51 using less_comparable = decltype(std::declval<L>() < std::declval<R>());
52 
53 template <typename L, typename R>
54 using greater_comparable = decltype(std::declval<L>() > std::declval<R>());
55 
56 template <typename L, typename R>
57 using equality_comparable = decltype(std::declval<L>() == std::declval<R>());
58 
59 namespace detail {
60 template <typename L, typename R, typename = void>
61 struct is_relationally_comparable_impl : std::false_type {
62 };
63 
64 template <typename L, typename R>
65 struct is_relationally_comparable_impl<L,
66  R,
67  void_t<less_comparable<L, R>, greater_comparable<L, R>>>
68  : std::true_type {
69 };
70 
71 template <typename L, typename R, typename = void>
72 struct is_equality_comparable_impl : std::false_type {
73 };
74 
75 template <typename L, typename R>
76 struct is_equality_comparable_impl<L, R, void_t<equality_comparable<L, R>>> : std::true_type {
77 };
78 
79 // has common type
80 template <typename AlwaysVoid, typename... Ts>
81 struct has_common_type_impl : std::false_type {
82 };
83 
84 template <typename... Ts>
85 struct has_common_type_impl<void_t<std::common_type_t<Ts...>>, Ts...> : std::true_type {
86 };
87 } // namespace detail
88 
89 template <typename... Ts>
90 using has_common_type = typename detail::has_common_type_impl<void, Ts...>::type;
91 
92 template <typename... Ts>
93 constexpr inline bool has_common_type_v = detail::has_common_type_impl<void, Ts...>::value;
94 
95 template <typename T>
96 using is_timestamp_t = cuda::std::disjunction<std::is_same<cudf::timestamp_D, T>,
97  std::is_same<cudf::timestamp_s, T>,
98  std::is_same<cudf::timestamp_ms, T>,
99  std::is_same<cudf::timestamp_us, T>,
100  std::is_same<cudf::timestamp_ns, T>>;
101 
102 template <typename T>
103 using is_duration_t = cuda::std::disjunction<std::is_same<cudf::duration_D, T>,
104  std::is_same<cudf::duration_s, T>,
105  std::is_same<cudf::duration_ms, T>,
106  std::is_same<cudf::duration_us, T>,
107  std::is_same<cudf::duration_ns, T>>;
108 
121 template <typename L, typename R>
122 constexpr inline bool is_relationally_comparable()
123 {
124  return detail::is_relationally_comparable_impl<L, R>::value;
125 }
126 
127 namespace detail {
132  template <typename T>
133  inline bool operator()() const
134  {
135  return cudf::is_relationally_comparable<T, T>();
136  }
137 };
138 } // namespace detail
139 
148 {
150 }
151 
164 template <typename L, typename R>
165 constexpr inline bool is_equality_comparable()
166 {
167  return detail::is_equality_comparable_impl<L, R>::value;
168 }
169 
170 namespace detail {
175  template <typename T>
176  bool operator()() const
177  {
178  return cudf::is_equality_comparable<T, T>();
179  }
180 };
181 } // namespace detail
182 
191 {
193 }
194 
202 template <typename T>
203 constexpr inline bool is_numeric()
204 {
205  return cuda::std::is_arithmetic<T>();
206 }
207 
208 struct is_numeric_impl {
209  template <typename T>
210  constexpr bool operator()()
211  {
212  return is_numeric<T>();
213  }
214 };
215 
227 constexpr inline bool is_numeric(data_type type)
228 {
229  return cudf::type_dispatcher(type, is_numeric_impl{});
230 }
231 
243 template <typename T>
244 constexpr inline bool is_index_type()
245 {
246  return std::is_integral_v<T> and not std::is_same_v<T, bool>;
247 }
248 
249 struct is_index_type_impl {
250  template <typename T>
251  constexpr bool operator()()
252  {
253  return is_index_type<T>();
254  }
255 };
256 
268 constexpr inline bool is_index_type(data_type type)
269 {
270  return cudf::type_dispatcher(type, is_index_type_impl{});
271 }
272 
280 template <typename T>
281 constexpr inline bool is_unsigned()
282 {
283  return std::is_unsigned_v<T>;
284 }
285 
286 struct is_unsigned_impl {
287  template <typename T>
288  constexpr bool operator()()
289  {
290  return is_unsigned<T>();
291  }
292 };
302 constexpr inline bool is_unsigned(data_type type)
303 {
304  return cudf::type_dispatcher(type, is_unsigned_impl{});
305 }
306 
313 template <typename Iterator>
314 constexpr inline bool is_signed_iterator()
315 {
316  return std::is_signed_v<typename std::iterator_traits<Iterator>::value_type>;
317 }
318 
326 template <typename T>
327 constexpr inline bool is_floating_point()
328 {
329  return std::is_floating_point_v<T>;
330 }
331 
332 struct is_floating_point_impl {
333  template <typename T>
334  constexpr bool operator()()
335  {
336  return is_floating_point<T>();
337  }
338 };
339 
349 constexpr inline bool is_floating_point(data_type type)
350 {
351  return cudf::type_dispatcher(type, is_floating_point_impl{});
352 }
353 
361 template <typename T>
362 constexpr inline bool is_boolean()
363 {
364  return std::is_same_v<T, bool>;
365 }
366 
367 struct is_boolean_impl {
368  template <typename T>
369  constexpr bool operator()()
370  {
371  return is_boolean<T>();
372  }
373 };
374 
382 constexpr inline bool is_boolean(data_type type)
383 {
384  return cudf::type_dispatcher(type, is_boolean_impl{});
385 }
386 
394 template <typename T>
395 constexpr inline bool is_timestamp()
396 {
397  return is_timestamp_t<T>::value;
398 }
399 
400 struct is_timestamp_impl {
401  template <typename T>
402  constexpr bool operator()()
403  {
404  return is_timestamp<T>();
405  }
406 };
407 
417 constexpr inline bool is_timestamp(data_type type)
418 {
419  return cudf::type_dispatcher(type, is_timestamp_impl{});
420 }
421 
429 template <typename T>
430 constexpr inline bool is_fixed_point()
431 {
432  return std::is_same_v<numeric::decimal32, T> || std::is_same_v<numeric::decimal64, T> ||
433  std::is_same_v<numeric::decimal128, T>;
434 }
435 
436 struct is_fixed_point_impl {
437  template <typename T>
438  constexpr bool operator()()
439  {
440  return is_fixed_point<T>();
441  }
442 };
443 
451 constexpr inline bool is_fixed_point(data_type type)
452 {
453  return cudf::type_dispatcher(type, is_fixed_point_impl{});
454 }
455 
463 template <typename T>
464 constexpr inline bool is_duration()
465 {
466  return is_duration_t<T>::value;
467 }
468 
469 struct is_duration_impl {
470  template <typename T>
471  constexpr bool operator()()
472  {
473  return is_duration<T>();
474  }
475 };
476 
486 constexpr inline bool is_duration(data_type type)
487 {
488  return cudf::type_dispatcher(type, is_duration_impl{});
489 }
490 
498 template <typename T>
499 constexpr inline bool is_chrono()
500 {
501  return is_duration<T>() || is_timestamp<T>();
502 }
503 
504 struct is_chrono_impl {
505  template <typename T>
506  constexpr bool operator()()
507  {
508  return is_chrono<T>();
509  }
510 };
511 
522 constexpr inline bool is_chrono(data_type type)
523 {
524  return cudf::type_dispatcher(type, is_chrono_impl{});
525 }
526 
538 template <typename T>
539 constexpr bool is_rep_layout_compatible()
540 {
541  return cudf::is_numeric<T>() or cudf::is_chrono<T>() or cudf::is_boolean<T>();
542 }
543 
551 template <typename T>
552 constexpr inline bool is_dictionary()
553 {
554  return std::is_same_v<dictionary32, T>;
555 }
556 
557 struct is_dictionary_impl {
558  template <typename T>
559  constexpr bool operator()()
560  {
561  return is_dictionary<T>();
562  }
563 };
564 
572 constexpr inline bool is_dictionary(data_type type)
573 {
574  return cudf::type_dispatcher(type, is_dictionary_impl{});
575 }
585 template <typename T>
586 constexpr inline bool is_fixed_width()
587 {
588  // TODO Add fixed width wrapper types
589  // Is a category fixed width?
590  return cudf::is_numeric<T>() || cudf::is_chrono<T>() || cudf::is_fixed_point<T>();
591 }
592 
593 struct is_fixed_width_impl {
594  template <typename T>
595  constexpr bool operator()()
596  {
597  return is_fixed_width<T>();
598  }
599 };
600 
610 constexpr inline bool is_fixed_width(data_type type)
611 {
612  return cudf::type_dispatcher(type, is_fixed_width_impl{});
613 }
614 
615 class string_view;
616 
629 template <typename T>
630 constexpr inline bool is_compound()
631 {
632  return std::is_same_v<T, cudf::string_view> or std::is_same_v<T, cudf::dictionary32> or
633  std::is_same_v<T, cudf::list_view> or std::is_same_v<T, cudf::struct_view>;
634 }
635 
636 struct is_compound_impl {
637  template <typename T>
638  constexpr bool operator()()
639  {
640  return is_compound<T>();
641  }
642 };
643 
656 constexpr inline bool is_compound(data_type type)
657 {
658  return cudf::type_dispatcher(type, is_compound_impl{});
659 }
660 
672 template <typename T>
673 constexpr inline bool is_nested()
674 {
675  return std::is_same_v<T, cudf::list_view> || std::is_same_v<T, cudf::struct_view>;
676 }
677 
678 struct is_nested_impl {
679  template <typename T>
680  constexpr bool operator()()
681  {
682  return is_nested<T>();
683  }
684 };
685 
697 constexpr inline bool is_nested(data_type type)
698 {
699  return cudf::type_dispatcher(type, is_nested_impl{});
700 }
701 
708 template <typename T>
709 constexpr inline bool is_struct()
710 {
711  return std::is_same_v<T, cudf::struct_view>;
712 }
713 
714 struct is_struct_impl {
715  template <typename T>
716  constexpr bool operator()()
717  {
718  return is_struct<T>();
719  }
720 };
721 
728 constexpr inline bool is_struct(data_type type)
729 {
730  return cudf::type_dispatcher(type, is_struct_impl{});
731 }
732 
733 template <typename FromType>
734 struct is_bit_castable_to_impl {
735  template <typename ToType, std::enable_if_t<is_compound<ToType>()>* = nullptr>
736  constexpr bool operator()()
737  {
738  return false;
739  }
740 
741  template <typename ToType, std::enable_if_t<not is_compound<ToType>()>* = nullptr>
742  constexpr bool operator()()
743  {
744  if (not cuda::std::is_trivially_copyable_v<FromType> ||
745  not cuda::std::is_trivially_copyable_v<ToType>) {
746  return false;
747  }
748  constexpr auto from_size = sizeof(cudf::device_storage_type_t<FromType>);
749  constexpr auto to_size = sizeof(cudf::device_storage_type_t<ToType>);
750  return from_size == to_size;
751  }
752 };
753 
754 struct is_bit_castable_from_impl {
755  template <typename FromType, std::enable_if_t<is_compound<FromType>()>* = nullptr>
756  constexpr bool operator()(data_type)
757  {
758  return false;
759  }
760 
761  template <typename FromType, std::enable_if_t<not is_compound<FromType>()>* = nullptr>
762  constexpr bool operator()(data_type to)
763  {
764  return cudf::type_dispatcher(to, is_bit_castable_to_impl<FromType>{});
765  }
766 };
767 
781 constexpr bool is_bit_castable(data_type from, data_type to)
782 {
783  return type_dispatcher(from, is_bit_castable_from_impl{}, to);
784 }
785 
786 template <typename From, typename To>
787 struct is_convertible : std::is_convertible<From, To> {
788 };
789 
790 // This will ensure that timestamps can be promoted to a higher precision. Presently, they can't
791 // do that due to nvcc/gcc compiler issues
792 template <typename Duration1, typename Duration2>
793 struct is_convertible<cudf::detail::timestamp<Duration1>, cudf::detail::timestamp<Duration2>>
794  : std::is_convertible<typename cudf::detail::time_point<Duration1>::duration,
795  typename cudf::detail::time_point<Duration2>::duration> {
796 };
797 
800 } // namespace cudf
durations.hpp
Concrete type definitions for int32_t and int64_t durations in varying resolutions.
cudf::is_bit_castable
constexpr bool is_bit_castable(data_type from, data_type to)
Indicates whether from is bit-castable to to.
Definition: traits.hpp:781
cudf::is_signed_iterator
constexpr bool is_signed_iterator()
Indicates whether the Iterator value type is unsigned.
Definition: traits.hpp:314
types.hpp
Type declarations for libcudf.
cudf::is_compound
constexpr bool is_compound()
Indicates whether the type T is a compound type.
Definition: traits.hpp:630
cudf::detail::unary_relationally_comparable_functor
Helper functor to check if a specified type T supports relational comparisons.
Definition: traits.hpp:131
cudf::is_boolean
constexpr bool is_boolean()
Indicates whether T is a Boolean type.
Definition: traits.hpp:362
cudf::is_rep_layout_compatible
constexpr bool is_rep_layout_compatible()
Indicates whether T is layout compatible with its "representation" type.
Definition: traits.hpp:539
cudf::is_numeric
constexpr bool is_numeric()
Indicates whether the type T is a numeric type.
Definition: traits.hpp:203
cudf::device_storage_type_t
std::conditional_t< std::is_same_v< numeric::decimal32, T >, int32_t, std::conditional_t< std::is_same_v< numeric::decimal64, T >, int64_t, std::conditional_t< std::is_same_v< numeric::decimal128, T >, __int128_t, T > >> device_storage_type_t
"Returns" the corresponding type that is stored on the device when using cudf::column
Definition: type_dispatcher.hpp:104
cudf::is_unsigned
constexpr bool is_unsigned()
Indicates whether the type T is a unsigned numeric type.
Definition: traits.hpp:281
cudf::is_struct
constexpr bool is_struct()
Indicates whether T is a struct type.
Definition: traits.hpp:709
cudf::type_dispatcher
CUDF_HOST_DEVICE constexpr decltype(auto) __forceinline__ type_dispatcher(cudf::data_type dtype, Functor f, Ts &&... args)
Invokes an operator() template with the type instantiation based on the specified cudf::data_type's i...
Definition: type_dispatcher.hpp:438
cudf::is_floating_point
constexpr bool is_floating_point()
Indicates whether the type T is a floating point type.
Definition: traits.hpp:327
cudf::detail::unary_equality_comparable_functor
Helper functor to check if a specified type T supports equality comparisons.
Definition: traits.hpp:174
cudf::is_dictionary
constexpr bool is_dictionary()
Indicates whether the type T is a dictionary type.
Definition: traits.hpp:552
cudf::data_type
Indicator for the logical data type of an element in a column.
Definition: types.hpp:240
cudf::is_index_type
constexpr bool is_index_type()
Indicates whether the type T is a index type.
Definition: traits.hpp:244
cudf
cuDF interfaces
Definition: aggregation.hpp:34
cudf::is_chrono
constexpr bool is_chrono()
Indicates whether the type T is a chrono type.
Definition: traits.hpp:499
cudf::is_fixed_width
constexpr bool is_fixed_width()
Indicates whether elements of type T are fixed-width.
Definition: traits.hpp:586
cudf::is_nested
constexpr bool is_nested()
Indicates whether T is a nested type.
Definition: traits.hpp:673
cudf::is_convertible
Definition: traits.hpp:787
cudf::is_fixed_point
constexpr bool is_fixed_point()
Indicates whether the type T is a fixed-point type.
Definition: traits.hpp:430
cudf::is_duration
constexpr bool is_duration()
Indicates whether the type T is a duration type.
Definition: traits.hpp:464
timestamps.hpp
Concrete type definitions for int32_t and int64_t timestamps in varying resolutions as durations sinc...
cudf::is_equality_comparable
constexpr bool is_equality_comparable()
Indicates whether objects of types L and R can be compared for equality.
Definition: traits.hpp:165
cudf::is_timestamp
constexpr bool is_timestamp()
Indicates whether the type T is a timestamp type.
Definition: traits.hpp:395
type_dispatcher.hpp
Defines the mapping between cudf::type_id runtime type information and concrete C++ types.
cudf::is_relationally_comparable
constexpr bool is_relationally_comparable()
Indicates whether objects of types L and R can be relationally compared.
Definition: traits.hpp:122