Skip to content

Commit 8d385f1

Browse files
authored
Merge pull request #65 from bemanproject/constexpr_example
Make sure constexpr functions are working under constexpr environment
2 parents 7355351 + 13eedc1 commit 8d385f1

File tree

6 files changed

+440
-16
lines changed

6 files changed

+440
-16
lines changed

README.md

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,14 @@ SPDX-License-Identifier: <SPDX License Expression>
44

55
# beman.inplace\_vector: Dynamically-resizable vector with fixed capacity
66

7-
<!-- markdownlint-disable -->
8-
<img src="https://github.com/bemanproject/beman/blob/main/images/logos/beman_logo-beman_library_under_development.png" style="width:5%; height:auto;"> ![Continuous Integration Tests](https://github.com/bemanproject/inplace_vector/actions/workflows/ci_tests.yml/badge.svg)
7+
![Library Status](https://github.com/bemanproject/beman/blob/c6997986557ec6dda98acbdf502082cdf7335526/images/badges/beman_badge-beman_library_under_development.svg)
8+
![Continuous Integration Tests](https://github.com/bemanproject/inplace_vector/actions/workflows/ci_tests.yml/badge.svg)
99
![Code Format](https://github.com/bemanproject/inplace_vector/actions/workflows/pre-commit.yml/badge.svg)
10-
<!-- markdownlint-enable -->
1110

1211
**Implements**: [`inplace_vector` (P0843R14)](https://wg21.link/P0843R14)
1312

14-
<!-- markdownlint-disable -->
15-
**Status**: [Under development and not yet ready for production use.](https://github.com/bemanproject/beman/blob/main/docs/BEMAN_LIBRARY_MATURITY_MODEL.md#under-development-and-not-yet-ready-for-production-use)
16-
<!-- markdownlint-enable -->
13+
**Status**:
14+
[Under development and not yet ready for production use.](https://github.com/bemanproject/beman/blob/main/docs/BEMAN_LIBRARY_MATURITY_MODEL.md#under-development-and-not-yet-ready-for-production-use)
1715

1816
## Usage
1917

@@ -30,13 +28,16 @@ which dynamic memory allocations are undesired.
3028
#### Note on implementation progress
3129

3230
Current implementation implements all public interfaces defined in the paper.
33-
However constexpr related functionalities are not tested and maybe broken.
3431

35-
There have been minor updates to the wording after the paper is accepted, notably [P3247](wg21.link/P3247).
32+
There have been minor updates to the wording after the paper is accepted,
33+
notably [P3247](wg21.link/P3247).
3634
Which changes the requirements for constexpr support.
3735
This will likely be preceded with [P3074](wg21.link/P3074).
3836
These has not been implemented yet.
3937

38+
You can follow [this link](eel.is/c++draft/inplace.vector)
39+
to checkout the status of `inplace_vector` in the latest draft.
40+
4041
Contributions are welcome.
4142

4243
### Code example
@@ -53,21 +54,46 @@ using namespace beman;
5354
* Generates fibonacci sequence using inplace_vector.
5455
* See: https://en.wikipedia.org/wiki/Fibonacci_sequence
5556
*/
56-
template <int Capacity> inplace_vector<int, Capacity> fibonacci_to(int num) {
57+
template <int Capacity>
58+
constexpr inplace_vector<int, Capacity> fibonacci_to(int num) {
5759
assert(num < Capacity);
5860

5961
inplace_vector<int, Capacity> vec;
6062

61-
constexpr static std::array<int, 2> first_two{0, 1};
63+
constexpr std::array<int, 2> first_two{0, 1};
6264
for (auto i = 0; i <= num; ++i) {
6365
auto new_val = i < 2 ? first_two[i] : vec[i - 1] + vec[i - 2];
6466
vec.push_back(new_val);
6567
}
6668

6769
return vec;
6870
}
71+
72+
/*
73+
* Check the result of the computation at compile time.
74+
*/
75+
constexpr bool check_5() {
76+
auto got = fibonacci_to<10>(5);
77+
constexpr inplace_vector<int, 10> correct{0, 1, 1, 2, 3, 5};
78+
return got == correct;
79+
}
80+
81+
static_assert(check_5());
82+
6983
```
7084
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+
7197
## How to Build
7298
7399
### Compiler support

examples/fibonacci.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@ using namespace beman;
1010
* Generates fibonacci sequence using inplace_vector.
1111
* See: https://en.wikipedia.org/wiki/Fibonacci_sequence
1212
*/
13-
template <int Capacity> inplace_vector<int, Capacity> fibonacci_to(int num) {
13+
template <int Capacity>
14+
constexpr inplace_vector<int, Capacity> fibonacci_to(int num) {
1415
assert(num < Capacity);
1516

1617
inplace_vector<int, Capacity> vec;
1718

18-
constexpr static std::array<int, 2> first_two{0, 1};
19+
constexpr std::array<int, 2> first_two{0, 1};
1920
for (auto i = 0; i <= num; ++i) {
2021
auto new_val = i < 2 ? first_two[i] : vec[i - 1] + vec[i - 2];
2122
vec.push_back(new_val);
@@ -24,6 +25,17 @@ template <int Capacity> inplace_vector<int, Capacity> fibonacci_to(int num) {
2425
return vec;
2526
}
2627

28+
/*
29+
* Check the result of the computation at compile time.
30+
*/
31+
constexpr bool check_5() {
32+
auto got = fibonacci_to<10>(5);
33+
constexpr inplace_vector<int, 10> correct{0, 1, 1, 2, 3, 5};
34+
return got == correct;
35+
}
36+
37+
static_assert(check_5());
38+
2739
/**
2840
* Expected program output:
2941
*

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/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,14 @@ add_gtest(triviality)
4040
add_gtest(constructors)
4141
add_gtest(size_n_data)
4242
add_gtest(erasure)
43+
44+
# constexpr test
45+
add_executable(beman.inplace_vector.tests.constexpr constexpr.test.cpp)
46+
target_link_libraries(
47+
beman.inplace_vector.tests.constexpr
48+
PRIVATE beman.inplace_vector
49+
)
50+
add_test(
51+
NAME beman.inplace_vector.tests.constexpr
52+
COMMAND beman.inplace_vector.tests.constexpr
53+
)

tests/beman/inplace_vector/README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,12 @@ Not tested for now.
5050
> then no `inplace_vector<T, N>` member functions are usable in
5151
> constant expressions.
5252
53-
Not tested for now.
53+
See [constexpr.test.cpp](constexpr.test.cpp),
54+
note that this test suite only ensure functions are usable in a constexpr
55+
environment.
56+
The validity of those functions are tested in the main test suite.
57+
This test also doesn't exhaustivly test constexpr functions' behavior
58+
when exception throwing is expected.
5459

5560
#### 6.5 Bad alloc requirement
5661

@@ -99,7 +104,6 @@ See [erasure.test.cpp](erasure.test.cpp)
99104

100105
## Known Issues/ Missed Tests
101106

102-
- Constexpr related functionalities.
103107
- Emplacement minimal copy/ construction.
104108
- Exception safety on mutation.
105109

0 commit comments

Comments
 (0)