Skip to content

Commit 4bb9a23

Browse files
Update cpp/src/arrow/type.h
Co-authored-by: Antoine Pitrou <pitrou@free.fr>
1 parent 02d4142 commit 4bb9a23

7 files changed

Lines changed: 47 additions & 42 deletions

File tree

cpp/src/arrow/scalar_test.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,7 @@ TEST(TestScalar, IdentityCast) {
180180
test_identity_cast_for_type(type);
181181
}
182182
for (auto& type : {
183-
arrow::fixed_size_list(arrow::int32(), 20),
184-
arrow::list(arrow::int32()),
183+
arrow::fixed_size_list(arrow::int32(), 20), arrow::list(arrow::int32()),
185184
arrow::large_list(arrow::int32()),
186185
// TODO(GH-45430): CastTo for ListView is not implemented yet.
187186
// arrow::list_view(arrow::int32()), arrow::large_list_view(arrow::int32())

cpp/src/arrow/type.cc

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3554,22 +3554,15 @@ const std::vector<Type::type>& DecimalTypeIds() {
35543554
}
35553555

35563556
Result<std::shared_ptr<DataType>> type_singleton(Type::type id) {
3557-
struct Visitor {
3558-
Result<std::shared_ptr<DataType>> result;
3559-
3560-
template <typename T>
3561-
Status Visit(const T* type) {
3562-
if constexpr (TypeTraits<T>::is_parameter_free) {
3563-
result = TypeTraits<T>::type_singleton();
3564-
return Status::OK();
3565-
}
3566-
return Status::TypeError("Type ", ToString(T::type_id), " is not a parameter-free type");
3557+
auto visit = [](auto type) -> Result<std::shared_ptr<DataType>> {
3558+
using T = std::decay_t<decltype(*type)>;
3559+
if constexpr (TypeTraits<T>::is_parameter_free) {
3560+
return TypeTraits<T>::type_singleton();
35673561
}
3562+
return Status::TypeError("Type ", internal::ToString(T::type_id),
3563+
" is not a parameter-free type");
35683564
};
3569-
3570-
Visitor visitor;
3571-
RETURN_NOT_OK(VisitTypeIdInline(id, &visitor));
3572-
return visitor.result;
3565+
return VisitTypeId(id, visit);
35733566
}
35743567

35753568
} // namespace arrow

cpp/src/arrow/type.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2653,8 +2653,8 @@ const std::vector<Type::type>& DecimalTypeIds();
26532653
/// this function will return an error.
26542654
///
26552655
/// \param[in] id The type ID to create a type instance for
2656-
/// \return Result with a shared pointer to the created DataType instance,
2657-
/// or an error if the type requires parameters
2656+
/// \return The type instance for the given type ID,
2657+
/// or a TypeError if the type requires parameters
26582658
ARROW_EXPORT
26592659
Result<std::shared_ptr<DataType>> type_singleton(Type::type id);
26602660

cpp/src/arrow/type_test.cc

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
#include "arrow/type_traits.h"
4141
#include "arrow/util/checked_cast.h"
4242
#include "arrow/util/key_value_metadata.h"
43-
#include "arrow/util/logging.h"
4443

4544
namespace arrow {
4645

@@ -55,20 +54,15 @@ TEST(TestTypeId, AllTypeIds) {
5554
TEST(TestTypeSingleton, ParameterFreeTypes) {
5655
// Test successful cases - parameter-free types (sample a few)
5756
std::vector<std::pair<Type::type, std::shared_ptr<DataType>>> cases = {
58-
{Type::NA, null()},
59-
{Type::BOOL, boolean()},
60-
{Type::INT32, int32()},
61-
{Type::STRING, utf8()},
62-
{Type::DATE32, date32()},
57+
{Type::NA, null()}, {Type::BOOL, boolean()}, {Type::INT32, int32()},
58+
{Type::STRING, utf8()}, {Type::DATE32, date32()},
6359
};
6460

6561
for (const auto& test_case : cases) {
66-
SCOPED_TRACE("Testing type: " + std::to_string(static_cast<int>(test_case.first)));
62+
ARROW_SCOPED_TRACE("Testing type: ", internal::ToString(test_case.first));
6763
auto result = type_singleton(test_case.first);
6864
ASSERT_OK_AND_ASSIGN(auto type, result);
69-
ASSERT_TRUE(type->Equals(*test_case.second))
70-
<< "Failed on type " << test_case.first << ". Expected "
71-
<< test_case.second->ToString() << " but got " << type->ToString();
65+
AssertTypeEqual(*type, *test_case.second);
7266
}
7367
}
7468

@@ -77,14 +71,7 @@ TEST(TestTypeSingleton, ParameterizedTypes) {
7771
auto result = type_singleton(Type::TIMESTAMP);
7872
ASSERT_RAISES(TypeError, result);
7973
EXPECT_THAT(result.status().message(),
80-
testing::HasSubstr("is not a parameter-free singleton type"));
81-
}
82-
83-
TEST(TestTypeSingleton, InvalidType) {
84-
// Test with an invalid type ID
85-
auto result = type_singleton(static_cast<Type::type>(9999));
86-
ASSERT_FALSE(result.ok());
87-
EXPECT_TRUE(result.status().IsTypeError());
74+
testing::HasSubstr("is not a parameter-free type"));
8875
}
8976

9077
template <typename ReprFunc>

cpp/src/arrow/type_traits.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616
// under the License.
1717

1818
#include "arrow/type_traits.h"
19-
#include "arrow/type.h"
19+
2020
#include "arrow/util/logging_internal.h"
2121

22+
namespace arrow {
23+
2224
int RequiredValueAlignmentForBuffer(Type::type type_id, int buffer_index) {
2325
if (buffer_index == 2 && type_id == Type::DENSE_UNION) {
2426
// A dense union array is the only array (so far) that requires alignment

cpp/src/arrow/type_traits.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,8 @@
2222
#include <type_traits>
2323
#include <vector>
2424

25-
#include "arrow/result.h"
2625
#include "arrow/type.h"
2726
#include "arrow/util/bit_util.h"
28-
#include "arrow/util/macros.h"
2927

3028
namespace arrow {
3129

cpp/src/arrow/visit_type_inline.h

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,8 @@ inline Status VisitTypeInline(const DataType& type, VISITOR* visitor, ARGS&&...
7171
/// \tparam ARGS Additional arguments, if any, will be passed to the Visit function after
7272
/// the `type` argument
7373
///
74-
/// Unlike VisitTypeInline which calls `visitor.Visit`, here `visitor`
74+
/// Unlike VisitTypeInline which calls `visitor->Visit`, here `visitor`
7575
/// itself is called.
76-
/// `visitor` must support a `const DataType&` argument as a fallback,
77-
/// in addition to concrete type classes.
7876
///
7977
/// The intent is for this to be called on a generic lambda
8078
/// that may internally use `if constexpr` or similar constructs.
@@ -114,4 +112,32 @@ inline Status VisitTypeIdInline(Type::type id, VISITOR* visitor, ARGS&&... args)
114112

115113
#undef TYPE_ID_VISIT_INLINE
116114

115+
#define TYPE_ID_VISIT_INLINE(TYPE_CLASS) \
116+
case TYPE_CLASS##Type::type_id: { \
117+
const TYPE_CLASS##Type* concrete_ptr = NULLPTR; \
118+
return std::forward<VISITOR>(visitor)(concrete_ptr, std::forward<ARGS>(args)...); \
119+
}
120+
121+
/// \brief Calls `visitor` with a nullptr of the corresponding concrete type class
122+
/// \tparam ARGS Additional arguments, if any, will be passed to the Visit function after
123+
/// the `type` argument
124+
///
125+
/// Unlike VisitTypeIdInline which calls `visitor->Visit`, here `visitor`
126+
/// itself is called.
127+
///
128+
/// The intent is for this to be called on a generic lambda
129+
/// that may internally use `if constexpr` or similar constructs.
130+
template <typename VISITOR, typename... ARGS>
131+
inline auto VisitTypeId(Type::type id, VISITOR&& visitor, ARGS&&... args)
132+
-> decltype(std::forward<VISITOR>(visitor)(std::declval<DataType*>(), args...)) {
133+
switch (id) {
134+
ARROW_GENERATE_FOR_ALL_TYPES(TYPE_ID_VISIT_INLINE);
135+
default:
136+
break;
137+
}
138+
return Status::NotImplemented("Type not implemented");
139+
}
140+
141+
#undef TYPE_ID_VISIT_INLINE
142+
117143
} // namespace arrow

0 commit comments

Comments
 (0)