Skip to content

Commit 012f77a

Browse files
fsaintjacqueswesm
authored andcommitted
ARROW-4268: [C++] Native C type TypeTraits
Add convenience support for native types, e.g. `TypeTraits<int8_t>` or `auto type = TypeTraits<bool>::singleton_type();`. This is very handy in tests. Author: François Saint-Jacques <fsaintjacques@gmail.com> Closes apache#3514 from fsaintjacques/ARROW-4268-compile-c-type-traits and squashes the following commits: 946851c <François Saint-Jacques> Make clang-format happy e55a7d7 <François Saint-Jacques> Use CTypeTraits and refactor stl f9d7d0c <François Saint-Jacques> Better param name dbb3114 <François Saint-Jacques> ARROW-4268: Native C type TypeTraits
1 parent ea63231 commit 012f77a

4 files changed

Lines changed: 102 additions & 182 deletions

File tree

cpp/src/arrow/stl.h

Lines changed: 5 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -24,47 +24,14 @@
2424
#include <vector>
2525

2626
#include "arrow/type.h"
27+
#include "arrow/type_traits.h"
2728

2829
namespace arrow {
2930

3031
class Schema;
3132

3233
namespace stl {
3334

34-
/// Traits meta class to map standard C/C++ types to equivalent Arrow types.
35-
template <typename T>
36-
struct ConversionTraits {};
37-
38-
#define ARROW_STL_CONVERSION(c_type, ArrowType_) \
39-
template <> \
40-
struct ConversionTraits<c_type> { \
41-
static std::shared_ptr<DataType> arrow_type() { \
42-
return std::make_shared<ArrowType_>(); \
43-
} \
44-
constexpr static bool nullable = false; \
45-
};
46-
47-
ARROW_STL_CONVERSION(bool, BooleanType)
48-
ARROW_STL_CONVERSION(int8_t, Int8Type)
49-
ARROW_STL_CONVERSION(int16_t, Int16Type)
50-
ARROW_STL_CONVERSION(int32_t, Int32Type)
51-
ARROW_STL_CONVERSION(int64_t, Int64Type)
52-
ARROW_STL_CONVERSION(uint8_t, UInt8Type)
53-
ARROW_STL_CONVERSION(uint16_t, UInt16Type)
54-
ARROW_STL_CONVERSION(uint32_t, UInt32Type)
55-
ARROW_STL_CONVERSION(uint64_t, UInt64Type)
56-
ARROW_STL_CONVERSION(float, FloatType)
57-
ARROW_STL_CONVERSION(double, DoubleType)
58-
ARROW_STL_CONVERSION(std::string, StringType)
59-
60-
template <typename value_c_type>
61-
struct ConversionTraits<std::vector<value_c_type>> {
62-
static std::shared_ptr<DataType> arrow_type() {
63-
return list(ConversionTraits<value_c_type>::arrow_type());
64-
}
65-
constexpr static bool nullable = false;
66-
};
67-
6835
/// Build an arrow::Schema based upon the types defined in a std::tuple-like structure.
6936
///
7037
/// While the type information is available at compile-time, we still need to add the
@@ -82,8 +49,8 @@ struct SchemaFromTuple {
8249
const std::vector<std::string>& names) {
8350
std::vector<std::shared_ptr<Field>> ret =
8451
SchemaFromTuple<Tuple, N - 1>::MakeSchemaRecursion(names);
85-
std::shared_ptr<DataType> type = ConversionTraits<Element>::arrow_type();
86-
ret.push_back(field(names[N - 1], type, ConversionTraits<Element>::nullable));
52+
std::shared_ptr<DataType> type = CTypeTraits<Element>::type_singleton();
53+
ret.push_back(field(names[N - 1], type, false /* nullable */));
8754
return ret;
8855
}
8956

@@ -111,9 +78,8 @@ struct SchemaFromTuple {
11178
const NamesTuple& names) {
11279
std::vector<std::shared_ptr<Field>> ret =
11380
SchemaFromTuple<Tuple, N - 1>::MakeSchemaRecursionT(names);
114-
std::shared_ptr<DataType> type = ConversionTraits<Element>::arrow_type();
115-
ret.push_back(
116-
field(std::get<N - 1>(names), type, ConversionTraits<Element>::nullable));
81+
std::shared_ptr<DataType> type = CTypeTraits<Element>::type_singleton();
82+
ret.push_back(field(std::get<N - 1>(names), type, false /* nullable */));
11783
return ret;
11884
}
11985

cpp/src/arrow/type-test.cc

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "arrow/memory_pool.h"
2828
#include "arrow/test-util.h"
2929
#include "arrow/type.h"
30+
#include "arrow/type_traits.h"
3031
#include "arrow/util/checked_cast.h"
3132

3233
using std::shared_ptr;
@@ -254,27 +255,34 @@ TEST_F(TestSchema, TestRemoveMetadata) {
254255
ASSERT_TRUE(new_schema->metadata() == nullptr);
255256
}
256257

257-
#define PRIMITIVE_TEST(KLASS, ENUM, NAME) \
258-
TEST(TypesTest, TestPrimitive_##ENUM) { \
259-
KLASS tp; \
260-
\
261-
ASSERT_EQ(tp.id(), Type::ENUM); \
262-
ASSERT_EQ(tp.ToString(), std::string(NAME)); \
258+
#define PRIMITIVE_TEST(KLASS, CTYPE, ENUM, NAME) \
259+
TEST(TypesTest, ARROW_CONCAT(TestPrimitive_, ENUM)) { \
260+
KLASS tp; \
261+
\
262+
ASSERT_EQ(tp.id(), Type::ENUM); \
263+
ASSERT_EQ(tp.ToString(), std::string(NAME)); \
264+
\
265+
using CType = TypeTraits<KLASS>::CType; \
266+
static_assert(std::is_same<CType, CTYPE>::value, "Not the same c-type!"); \
267+
\
268+
using DerivedArrowType = CTypeTraits<CTYPE>::ArrowType; \
269+
static_assert(std::is_same<DerivedArrowType, KLASS>::value, \
270+
"Not the same arrow-type!"); \
263271
}
264272

265-
PRIMITIVE_TEST(Int8Type, INT8, "int8")
266-
PRIMITIVE_TEST(Int16Type, INT16, "int16")
267-
PRIMITIVE_TEST(Int32Type, INT32, "int32")
268-
PRIMITIVE_TEST(Int64Type, INT64, "int64")
269-
PRIMITIVE_TEST(UInt8Type, UINT8, "uint8")
270-
PRIMITIVE_TEST(UInt16Type, UINT16, "uint16")
271-
PRIMITIVE_TEST(UInt32Type, UINT32, "uint32")
272-
PRIMITIVE_TEST(UInt64Type, UINT64, "uint64")
273+
PRIMITIVE_TEST(Int8Type, int8_t, INT8, "int8");
274+
PRIMITIVE_TEST(Int16Type, int16_t, INT16, "int16");
275+
PRIMITIVE_TEST(Int32Type, int32_t, INT32, "int32");
276+
PRIMITIVE_TEST(Int64Type, int64_t, INT64, "int64");
277+
PRIMITIVE_TEST(UInt8Type, uint8_t, UINT8, "uint8");
278+
PRIMITIVE_TEST(UInt16Type, uint16_t, UINT16, "uint16");
279+
PRIMITIVE_TEST(UInt32Type, uint32_t, UINT32, "uint32");
280+
PRIMITIVE_TEST(UInt64Type, uint64_t, UINT64, "uint64");
273281

274-
PRIMITIVE_TEST(FloatType, FLOAT, "float")
275-
PRIMITIVE_TEST(DoubleType, DOUBLE, "double")
282+
PRIMITIVE_TEST(FloatType, float, FLOAT, "float");
283+
PRIMITIVE_TEST(DoubleType, double, DOUBLE, "double");
276284

277-
PRIMITIVE_TEST(BooleanType, BOOL, "bool")
285+
PRIMITIVE_TEST(BooleanType, bool, BOOL, "bool");
278286

279287
TEST(TestBinaryType, ToString) {
280288
BinaryType t1;

cpp/src/arrow/type_traits.h

Lines changed: 71 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
#define ARROW_TYPE_TRAITS_H
2020

2121
#include <memory>
22+
#include <string>
2223
#include <type_traits>
24+
#include <vector>
2325

2426
#include "arrow/type_fwd.h"
2527
#include "arrow/util/bit-util.h"
@@ -33,6 +35,9 @@ namespace arrow {
3335
template <typename T>
3436
struct TypeTraits {};
3537

38+
template <typename T>
39+
struct CTypeTraits {};
40+
3641
template <>
3742
struct TypeTraits<NullType> {
3843
using ArrayType = NullArray;
@@ -41,102 +46,61 @@ struct TypeTraits<NullType> {
4146
};
4247

4348
template <>
44-
struct TypeTraits<UInt8Type> {
45-
using ArrayType = UInt8Array;
46-
using BuilderType = UInt8Builder;
47-
using TensorType = UInt8Tensor;
48-
static constexpr int64_t bytes_required(int64_t elements) { return elements; }
49-
constexpr static bool is_parameter_free = true;
50-
static inline std::shared_ptr<DataType> type_singleton() { return uint8(); }
51-
};
52-
53-
template <>
54-
struct TypeTraits<Int8Type> {
55-
using ArrayType = Int8Array;
56-
using BuilderType = Int8Builder;
57-
using TensorType = Int8Tensor;
58-
static constexpr int64_t bytes_required(int64_t elements) { return elements; }
59-
constexpr static bool is_parameter_free = true;
60-
static inline std::shared_ptr<DataType> type_singleton() { return int8(); }
61-
};
62-
63-
template <>
64-
struct TypeTraits<UInt16Type> {
65-
using ArrayType = UInt16Array;
66-
using BuilderType = UInt16Builder;
67-
using TensorType = UInt16Tensor;
68-
69-
static constexpr int64_t bytes_required(int64_t elements) {
70-
return elements * sizeof(uint16_t);
71-
}
72-
constexpr static bool is_parameter_free = true;
73-
static inline std::shared_ptr<DataType> type_singleton() { return uint16(); }
74-
};
75-
76-
template <>
77-
struct TypeTraits<Int16Type> {
78-
using ArrayType = Int16Array;
79-
using BuilderType = Int16Builder;
80-
using TensorType = Int16Tensor;
81-
82-
static constexpr int64_t bytes_required(int64_t elements) {
83-
return elements * sizeof(int16_t);
84-
}
85-
constexpr static bool is_parameter_free = true;
86-
static inline std::shared_ptr<DataType> type_singleton() { return int16(); }
87-
};
88-
89-
template <>
90-
struct TypeTraits<UInt32Type> {
91-
using ArrayType = UInt32Array;
92-
using BuilderType = UInt32Builder;
93-
using TensorType = UInt32Tensor;
94-
95-
static constexpr int64_t bytes_required(int64_t elements) {
96-
return elements * sizeof(uint32_t);
97-
}
98-
constexpr static bool is_parameter_free = true;
99-
static inline std::shared_ptr<DataType> type_singleton() { return uint32(); }
100-
};
101-
102-
template <>
103-
struct TypeTraits<Int32Type> {
104-
using ArrayType = Int32Array;
105-
using BuilderType = Int32Builder;
106-
using TensorType = Int32Tensor;
107-
108-
static constexpr int64_t bytes_required(int64_t elements) {
109-
return elements * sizeof(int32_t);
110-
}
111-
constexpr static bool is_parameter_free = true;
112-
static inline std::shared_ptr<DataType> type_singleton() { return int32(); }
113-
};
114-
115-
template <>
116-
struct TypeTraits<UInt64Type> {
117-
using ArrayType = UInt64Array;
118-
using BuilderType = UInt64Builder;
119-
using TensorType = UInt64Tensor;
49+
struct TypeTraits<BooleanType> {
50+
using ArrayType = BooleanArray;
51+
using BuilderType = BooleanBuilder;
52+
using CType = bool;
12053

12154
static constexpr int64_t bytes_required(int64_t elements) {
122-
return elements * sizeof(uint64_t);
55+
return BitUtil::BytesForBits(elements);
12356
}
12457
constexpr static bool is_parameter_free = true;
125-
static inline std::shared_ptr<DataType> type_singleton() { return uint64(); }
58+
static inline std::shared_ptr<DataType> type_singleton() { return boolean(); }
12659
};
12760

12861
template <>
129-
struct TypeTraits<Int64Type> {
130-
using ArrayType = Int64Array;
131-
using BuilderType = Int64Builder;
132-
using TensorType = Int64Tensor;
62+
struct CTypeTraits<bool> : public TypeTraits<BooleanType> {
63+
using ArrowType = BooleanType;
64+
};
65+
66+
#define PRIMITIVE_TYPE_TRAITS_DEF_(CType_, ArrowType_, ArrowArrayType, ArrowBuilderType, \
67+
ArrowTensorType, SingletonFn) \
68+
template <> \
69+
struct TypeTraits<ArrowType_> { \
70+
using ArrayType = ArrowArrayType; \
71+
using BuilderType = ArrowBuilderType; \
72+
using TensorType = ArrowTensorType; \
73+
using CType = CType_; \
74+
static constexpr int64_t bytes_required(int64_t elements) { \
75+
return elements * sizeof(CType_); \
76+
} \
77+
constexpr static bool is_parameter_free = true; \
78+
static inline std::shared_ptr<DataType> type_singleton() { return SingletonFn(); } \
79+
}; \
80+
\
81+
template <> \
82+
struct CTypeTraits<CType_> : public TypeTraits<ArrowType_> { \
83+
using ArrowType = ArrowType_; \
84+
};
13385

134-
static constexpr int64_t bytes_required(int64_t elements) {
135-
return elements * sizeof(int64_t);
136-
}
137-
constexpr static bool is_parameter_free = true;
138-
static inline std::shared_ptr<DataType> type_singleton() { return int64(); }
139-
};
86+
#define PRIMITIVE_TYPE_TRAITS_DEF(CType, ArrowShort, SingletonFn) \
87+
PRIMITIVE_TYPE_TRAITS_DEF_( \
88+
CType, ARROW_CONCAT(ArrowShort, Type), ARROW_CONCAT(ArrowShort, Array), \
89+
ARROW_CONCAT(ArrowShort, Builder), ARROW_CONCAT(ArrowShort, Tensor), SingletonFn)
90+
91+
PRIMITIVE_TYPE_TRAITS_DEF(uint8_t, UInt8, uint8)
92+
PRIMITIVE_TYPE_TRAITS_DEF(int8_t, Int8, int8)
93+
PRIMITIVE_TYPE_TRAITS_DEF(uint16_t, UInt16, uint16)
94+
PRIMITIVE_TYPE_TRAITS_DEF(int16_t, Int16, int16)
95+
PRIMITIVE_TYPE_TRAITS_DEF(uint32_t, UInt32, uint32)
96+
PRIMITIVE_TYPE_TRAITS_DEF(int32_t, Int32, int32)
97+
PRIMITIVE_TYPE_TRAITS_DEF(uint64_t, UInt64, uint64)
98+
PRIMITIVE_TYPE_TRAITS_DEF(int64_t, Int64, int64)
99+
PRIMITIVE_TYPE_TRAITS_DEF(float, Float, float32)
100+
PRIMITIVE_TYPE_TRAITS_DEF(double, Double, float64)
101+
102+
#undef PRIMITIVE_TYPE_TRAITS_DEF
103+
#undef PRIMITIVE_TYPE_TRAITS_DEF_
140104

141105
template <>
142106
struct TypeTraits<Date64Type> {
@@ -208,51 +172,13 @@ struct TypeTraits<HalfFloatType> {
208172
static inline std::shared_ptr<DataType> type_singleton() { return float16(); }
209173
};
210174

211-
template <>
212-
struct TypeTraits<FloatType> {
213-
using ArrayType = FloatArray;
214-
using BuilderType = FloatBuilder;
215-
using TensorType = FloatTensor;
216-
217-
static constexpr int64_t bytes_required(int64_t elements) {
218-
return static_cast<int64_t>(elements * sizeof(float));
219-
}
220-
constexpr static bool is_parameter_free = true;
221-
static inline std::shared_ptr<DataType> type_singleton() { return float32(); }
222-
};
223-
224-
template <>
225-
struct TypeTraits<DoubleType> {
226-
using ArrayType = DoubleArray;
227-
using BuilderType = DoubleBuilder;
228-
using TensorType = DoubleTensor;
229-
230-
static constexpr int64_t bytes_required(int64_t elements) {
231-
return static_cast<int64_t>(elements * sizeof(double));
232-
}
233-
constexpr static bool is_parameter_free = true;
234-
static inline std::shared_ptr<DataType> type_singleton() { return float64(); }
235-
};
236-
237175
template <>
238176
struct TypeTraits<Decimal128Type> {
239177
using ArrayType = Decimal128Array;
240178
using BuilderType = Decimal128Builder;
241179
constexpr static bool is_parameter_free = false;
242180
};
243181

244-
template <>
245-
struct TypeTraits<BooleanType> {
246-
using ArrayType = BooleanArray;
247-
using BuilderType = BooleanBuilder;
248-
249-
static constexpr int64_t bytes_required(int64_t elements) {
250-
return BitUtil::BytesForBits(elements);
251-
}
252-
constexpr static bool is_parameter_free = true;
253-
static inline std::shared_ptr<DataType> type_singleton() { return boolean(); }
254-
};
255-
256182
template <>
257183
struct TypeTraits<StringType> {
258184
using ArrayType = StringArray;
@@ -261,6 +187,16 @@ struct TypeTraits<StringType> {
261187
static inline std::shared_ptr<DataType> type_singleton() { return utf8(); }
262188
};
263189

190+
template <>
191+
struct CTypeTraits<std::string> : public TypeTraits<StringType> {
192+
using ArrowType = StringType;
193+
};
194+
195+
template <>
196+
struct CTypeTraits<char*> : public TypeTraits<StringType> {
197+
using ArrowType = StringType;
198+
};
199+
264200
template <>
265201
struct TypeTraits<BinaryType> {
266202
using ArrayType = BinaryArray;
@@ -283,6 +219,15 @@ struct TypeTraits<ListType> {
283219
constexpr static bool is_parameter_free = false;
284220
};
285221

222+
template <typename CType>
223+
struct CTypeTraits<std::vector<CType>> : public TypeTraits<ListType> {
224+
using ArrowType = ListType;
225+
226+
static inline std::shared_ptr<DataType> type_singleton() {
227+
return list(CTypeTraits<CType>::type_singleton());
228+
}
229+
};
230+
286231
template <>
287232
struct TypeTraits<StructType> {
288233
using ArrayType = StructArray;

cpp/src/arrow/util/macros.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define ARROW_UTIL_MACROS_H
2020

2121
#define ARROW_STRINGIFY(x) #x
22+
#define ARROW_CONCAT(x, y) x##y
2223

2324
// From Google gutil
2425
#ifndef ARROW_DISALLOW_COPY_AND_ASSIGN

0 commit comments

Comments
 (0)