-
Notifications
You must be signed in to change notification settings - Fork 73
/
Copy path351.md
109 lines (82 loc) · 2.14 KB
/
351.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
<details open><summary>Info</summary><p>
* **Did you know about C++26 proposal - `inplace_vector`?**
* https://wg21.link/P0843
</p></details><details open><summary>Example</summary><p>
```cpp
int main() {
std::inplace_vector<int, 2> v{};
assert(v.empty());
v.push_back(1);
assert(1 == v.size());
v.push_back(2);
assert(2 == v.size());
v.push_back(3); // throws
}
```
> https://godbolt.org/z/o365eWeEb
</p></details><details open><summary>Puzzle</summary><p>
* **Can you implement simplified constexpr version of inplace_vector?**
```cpp
template<class T, auto Size>
class inplace_vector; // TODO
static_assert([] {
inplace_vector<int, 1> v{};
v.push_back(1);
return v.size();
}() == 1);
static_assert([] {
inplace_vector<int, 2> v{};
v.push_back(1);
v.push_back(2);
return v.size();
}() == 2);
static_assert([] {
inplace_vector<int, 2> v{};
v.push_back(4);
v.push_back(2);
return v[0] + v[1];
}() == 6);
// should not compile
static_assert([] {
inplace_vector<int, 2> v{};
v.push_back(1);
v.push_back(2);
v.push_back(3);
return v.size();
}() == 2)
```
> https://godbolt.org/z/z51faxfa9
</p></details>
</p></details><details><summary>Solutions</summary><p>
```cpp
template <class T, auto Size>
struct inplace_vector {
constexpr void push_back(T value) { data_[index_++] = value; }
constexpr const auto& operator[](auto index) const { return data_[index]; }
constexpr auto size() const { return index_; }
constexpr auto clear() { index_ = {}; }
private:
std::array<T, Size> data_{};
std::size_t index_{};
};
```
> https://godbolt.org/z/acsa59PdG
```cpp
template <class T, auto Size>
class inplace_vector {
public:
constexpr T& push_back(const T& t) {
if (size_ == Size) {
throw std::bad_alloc();
}
return arr_[size_++].emplace(t);
}
constexpr std::size_t size() const { return size_; }
constexpr T& operator[](std::size_t idx) { return *arr_[idx]; }
private:
std::array<std::optional<T>, Size> arr_;
std::size_t size_ = 0;
};
```
> https://godbolt.org/z/scz4EfTa5
</p></details>