Skip to content

Commit 37f42ca

Browse files
committed
fix build: simplify traits in utils::Box
commit_hash:3bd2150c93c0b07c19a096c597e40ff319fdde6b
1 parent 9c57859 commit 37f42ca

File tree

3 files changed

+25
-59
lines changed

3 files changed

+25
-59
lines changed

chaotic/include/userver/chaotic/ref.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ struct Ref {
1515

1616
template <typename Value, typename T>
1717
utils::Box<formats::common::ParseType<Value, T>> Parse(const Value& value, formats::parse::To<Ref<T>>) {
18-
auto result = value.template As<T>();
19-
return result;
18+
return utils::Box<formats::common::ParseType<Value, T>>::MakeWithFactory([&value] { return value.template As<T>(); }
19+
);
2020
}
2121

2222
template <typename Value, typename T>

universal/include/userver/utils/box.hpp

Lines changed: 22 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
/// @file userver/utils/box.hpp
44
/// @brief @copybrief utils::Box
55

6+
#include <concepts>
67
#include <memory>
78
#include <type_traits>
89
#include <utility>
@@ -16,19 +17,16 @@ USERVER_NAMESPACE_BEGIN
1617

1718
namespace utils {
1819

20+
template <typename T>
21+
class Box;
22+
1923
namespace impl {
2024

21-
template <typename Self, typename... Args>
22-
inline constexpr bool kArgsAreNotSelf = ((sizeof...(Args) > 1) || ... || !std::is_same_v<std::decay_t<Args>, Self>);
25+
template <typename T>
26+
struct IsBox : std::false_type {};
2327

24-
template <bool Condition, template <typename...> typename Trait, typename... Args>
25-
constexpr bool ConjunctionWithTrait() noexcept {
26-
if constexpr (Condition) {
27-
return Trait<Args...>::value;
28-
} else {
29-
return false;
30-
}
31-
}
28+
template <typename... Args>
29+
struct IsBox<Box<Args...>> : std::true_type {};
3230

3331
} // namespace impl
3432

@@ -61,37 +59,22 @@ class Box {
6159
{}
6260

6361
/// Allocate a `T`, copying or moving @a arg.
64-
template <
65-
typename U = T,
66-
std::enable_if_t<
67-
impl::ConjunctionWithTrait<
68-
// Protection against hiding special
69-
// constructors.
70-
impl::kArgsAreNotSelf<Box, U>,
71-
// Only allow the implicit conversion to Box<T>
72-
// if U is implicitly convertible to T. Also,
73-
// support SFINAE.
74-
std::is_convertible,
75-
U&&,
76-
T>(),
77-
int> = 0>
78-
/*implicit*/ Box(U&& arg)
62+
template <typename U = T>
63+
// Protect against hiding special constructors.
64+
requires(!std::same_as<std::remove_cvref_t<U>, Box>) &&
65+
// Prevent infinite recursion from constructible_from in the next check.
66+
(!impl::IsBox<std::remove_cvref_t<U>>::value) &&
67+
// Prevent infinite recursion.
68+
(std::same_as<std::remove_cvref_t<U>, T> || !std::is_constructible_v<T, Box>) &&
69+
// Normal requirement.
70+
std::is_constructible_v<T, U>
71+
explicit(!std::convertible_to<U, T>) Box(U&& arg)
7972
: data_(std::make_unique<T>(std::forward<U>(arg)))
8073
{}
8174

8275
/// Allocate the value, emplacing it with the given @a args.
83-
template <
84-
typename... Args,
85-
std::enable_if_t<
86-
impl::ConjunctionWithTrait<
87-
// Protection against hiding special
88-
// constructors.
89-
impl::kArgsAreNotSelf<Box, Args...>,
90-
// Support SFINAE.
91-
std::is_constructible,
92-
T,
93-
Args&&...>(),
94-
int> = 0>
76+
template <typename... Args>
77+
requires(sizeof...(Args) >= 2) && std::is_constructible_v<T, Args...>
9578
explicit Box(Args&&... args)
9679
: data_(std::make_unique<T>(std::forward<Args>(args)...))
9780
{}
@@ -116,22 +99,8 @@ class Box {
11699
}
117100

118101
/// Assigns-through to the contained value.
119-
template <
120-
typename U = T,
121-
std::enable_if_t<
122-
impl::ConjunctionWithTrait< //
123-
impl::ConjunctionWithTrait<
124-
// Protection against hiding
125-
// special constructors.
126-
impl::kArgsAreNotSelf<Box, U>,
127-
// Support SFINAE.
128-
std::is_constructible,
129-
T,
130-
U>(),
131-
std::is_assignable,
132-
T&,
133-
U>(),
134-
int> = 0>
102+
template <typename U = T>
103+
requires(!std::same_as<std::remove_cvref_t<U>, Box>) && std::is_assignable_v<T&, U>
135104
Box& operator=(U&& other) {
136105
if (data_) {
137106
*data_ = std::forward<U>(other);

universal/src/utils/box_test.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ struct PackSection;
1818

1919
bool operator==(const RecursionStarterPack&, const RecursionStarterPack&);
2020
bool operator==(const PackSection&, const PackSection&);
21-
bool operator!=(const PackSection&, const PackSection&);
2221

2322
/// [sample]
2423
struct RecursionStarterPack {
@@ -59,12 +58,10 @@ bool operator==(const RecursionStarterPack& lhs, const RecursionStarterPack& rhs
5958
std::tie(rhs.structs, rhs.strings, rhs.whats_in_this_section);
6059
}
6160

62-
bool operator==(const PackSection& lhs, const PackSection& rhs) {
61+
[[maybe_unused]] bool operator==(const PackSection& lhs, const PackSection& rhs) {
6362
return std::tie(lhs.box, lhs.here_we_go_again) == std::tie(rhs.box, rhs.here_we_go_again);
6463
}
6564

66-
bool operator!=(const PackSection& lhs, const PackSection& rhs) { return !(lhs == rhs); }
67-
6865
struct NonDefaulted final {
6966
explicit NonDefaulted(int) {}
7067
};

0 commit comments

Comments
 (0)