Skip to content

Commit

Permalink
add beman::has_constexpr_support
Browse files Browse the repository at this point in the history
  • Loading branch information
wusatosi committed Jan 31, 2025
1 parent 04e68c3 commit 13eedc1
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 2 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,18 @@ static_assert(check_5());

```
### Note on constexpr support
Since `constexpr` requirements are actively changing,
you can use `beman::has_constexpr_support` to detect if our implementation
provide constexpr support for a specific specialization of `inplace_vector`.
Note this is not part of the standard Library and should not be relied on once
`constexpr` requirement stabilize.
Example Usage:
`static_assert(beman::has_constexpr_support<beman::inplace_vector<int, 5>>)`.
## How to Build
### Compiler support
Expand Down
12 changes: 10 additions & 2 deletions include/beman/inplace_vector/inplace_vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,9 @@ concept container_compatible_range =
std::ranges::input_range<Rng> &&
std::convertible_to<std::ranges::range_reference_t<Rng>, T>;

template <typename T, std::size_t N>
concept satify_constexpr = N == 0 || std::is_trivial_v<T>;

} // namespace beman::details::inplace_vector

// Types implementing the `inplace_vector`'s storage
Expand Down Expand Up @@ -425,13 +428,18 @@ template <class T, size_t N> struct non_trivial {
// Selects the vector storage.
template <class T, size_t N>
using storage_for = std::conditional_t<
N == 0, zero_sized<T>,
std::conditional_t<std::is_trivial_v<T>, trivial<T, N>, non_trivial<T, N>>>;
!satify_constexpr<T, N>, non_trivial<T, N>,
std::conditional_t<N == 0, zero_sized<T>, trivial<T, N>>>;

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

namespace beman {

template <typename IV>
concept has_constexpr_support =
details::inplace_vector::satify_constexpr<typename IV::value_type,
IV::capacity()>;

/// Dynamically-resizable fixed-N vector with inplace storage.
template <class T, size_t N>
struct inplace_vector
Expand Down
19 changes: 19 additions & 0 deletions tests/beman/inplace_vector/constexpr.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
#include <beman/inplace_vector/inplace_vector.hpp>
#include <type_traits>

// used for testing beman::has_constexpr_support
#include <memory>
#include <string>

/**
* These tests are only meant to test that suitable constexpr functions compiles
* in a constant evaluation environment.
Expand All @@ -25,6 +29,18 @@ struct Some {
};
static_assert(std::is_trivial_v<Some>);

using beman::has_constexpr_support;
using beman::inplace_vector;

static_assert(has_constexpr_support<inplace_vector<int, 50>>);
static_assert(has_constexpr_support<inplace_vector<Some, 50>>);

static_assert(has_constexpr_support<inplace_vector<std::string, 0>>);
static_assert(!has_constexpr_support<inplace_vector<std::string, 50>>);

static_assert(has_constexpr_support<inplace_vector<std::unique_ptr<int>, 0>>);
static_assert(!has_constexpr_support<inplace_vector<std::unique_ptr<int>, 50>>);

#define TEST(NAME) \
static_assert(std::invoke([]() { \
NAME<beman::inplace_vector<int, 20>>(); \
Expand Down Expand Up @@ -268,6 +284,9 @@ struct Complex {
};
static_assert(!std::is_trivially_default_constructible_v<Complex>);

static_assert(has_constexpr_support<inplace_vector<Complex, 0>>);
static_assert(!has_constexpr_support<inplace_vector<Complex, 50>>);

#define TEST_EMPTY(NAME) \
static_assert(std::invoke([]() { \
NAME<Complex>(); \
Expand Down

0 comments on commit 13eedc1

Please sign in to comment.