Skip to content

Commit 13eedc1

Browse files
committed
add beman::has_constexpr_support
1 parent 04e68c3 commit 13eedc1

File tree

3 files changed

+41
-2
lines changed

3 files changed

+41
-2
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,18 @@ static_assert(check_5());
8282

8383
```
8484
85+
### Note on constexpr support
86+
87+
Since `constexpr` requirements are actively changing,
88+
you can use `beman::has_constexpr_support` to detect if our implementation
89+
provide constexpr support for a specific specialization of `inplace_vector`.
90+
91+
Note this is not part of the standard Library and should not be relied on once
92+
`constexpr` requirement stabilize.
93+
94+
Example Usage:
95+
`static_assert(beman::has_constexpr_support<beman::inplace_vector<int, 5>>)`.
96+
8597
## How to Build
8698
8799
### Compiler support

include/beman/inplace_vector/inplace_vector.hpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,9 @@ concept container_compatible_range =
306306
std::ranges::input_range<Rng> &&
307307
std::convertible_to<std::ranges::range_reference_t<Rng>, T>;
308308

309+
template <typename T, std::size_t N>
310+
concept satify_constexpr = N == 0 || std::is_trivial_v<T>;
311+
309312
} // namespace beman::details::inplace_vector
310313

311314
// Types implementing the `inplace_vector`'s storage
@@ -425,13 +428,18 @@ template <class T, size_t N> struct non_trivial {
425428
// Selects the vector storage.
426429
template <class T, size_t N>
427430
using storage_for = std::conditional_t<
428-
N == 0, zero_sized<T>,
429-
std::conditional_t<std::is_trivial_v<T>, trivial<T, N>, non_trivial<T, N>>>;
431+
!satify_constexpr<T, N>, non_trivial<T, N>,
432+
std::conditional_t<N == 0, zero_sized<T>, trivial<T, N>>>;
430433

431434
} // namespace beman::details::inplace_vector::storage
432435

433436
namespace beman {
434437

438+
template <typename IV>
439+
concept has_constexpr_support =
440+
details::inplace_vector::satify_constexpr<typename IV::value_type,
441+
IV::capacity()>;
442+
435443
/// Dynamically-resizable fixed-N vector with inplace storage.
436444
template <class T, size_t N>
437445
struct inplace_vector

tests/beman/inplace_vector/constexpr.test.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
#include <beman/inplace_vector/inplace_vector.hpp>
33
#include <type_traits>
44

5+
// used for testing beman::has_constexpr_support
6+
#include <memory>
7+
#include <string>
8+
59
/**
610
* These tests are only meant to test that suitable constexpr functions compiles
711
* in a constant evaluation environment.
@@ -25,6 +29,18 @@ struct Some {
2529
};
2630
static_assert(std::is_trivial_v<Some>);
2731

32+
using beman::has_constexpr_support;
33+
using beman::inplace_vector;
34+
35+
static_assert(has_constexpr_support<inplace_vector<int, 50>>);
36+
static_assert(has_constexpr_support<inplace_vector<Some, 50>>);
37+
38+
static_assert(has_constexpr_support<inplace_vector<std::string, 0>>);
39+
static_assert(!has_constexpr_support<inplace_vector<std::string, 50>>);
40+
41+
static_assert(has_constexpr_support<inplace_vector<std::unique_ptr<int>, 0>>);
42+
static_assert(!has_constexpr_support<inplace_vector<std::unique_ptr<int>, 50>>);
43+
2844
#define TEST(NAME) \
2945
static_assert(std::invoke([]() { \
3046
NAME<beman::inplace_vector<int, 20>>(); \
@@ -268,6 +284,9 @@ struct Complex {
268284
};
269285
static_assert(!std::is_trivially_default_constructible_v<Complex>);
270286

287+
static_assert(has_constexpr_support<inplace_vector<Complex, 0>>);
288+
static_assert(!has_constexpr_support<inplace_vector<Complex, 50>>);
289+
271290
#define TEST_EMPTY(NAME) \
272291
static_assert(std::invoke([]() { \
273292
NAME<Complex>(); \

0 commit comments

Comments
 (0)