-
Notifications
You must be signed in to change notification settings - Fork 38
/
Copy pathbox.hpp
57 lines (46 loc) · 1.02 KB
/
box.hpp
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
/**
* Copyright Quadrivium LLC
* All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <iostream>
#include <type_traits>
template <typename T>
struct Box {
using Type = T;
template <typename... A>
explicit Box(A &&...args) : t_{std::forward<A>(args)...} {}
Box(Box &box) : Box{std::move(box)} {}
Box(Box &&box) : t_{std::move(*box.t_)} {
if constexpr (not std::is_standard_layout_v<T>
or not std::is_trivial_v<T>) {
box.t_ = std::nullopt;
}
}
Box &operator=(Box &val) {
return operator=(std::move(val));
}
Box &operator=(Box &&box) {
t_ = std::move(*box.t_);
if constexpr (not std::is_standard_layout_v<T>
or not std::is_trivial_v<T>) {
box.t_ = std::nullopt;
}
return *this;
}
auto clone() const {
assert(t_);
return Box<T>{*t_};
}
T &mut_value() & {
assert(t_);
return *t_;
}
const T &value() const & {
assert(t_);
return *t_;
}
private:
std::optional<T> t_;
};