-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstrong_typedef.h
64 lines (50 loc) · 1.27 KB
/
strong_typedef.h
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
//
// Created by Eli Winkelman on 8/21/19.
//
#ifndef UNTITLED_STRONG_TYPEDEF_H
#define UNTITLED_STRONG_TYPEDEF_H
#include "utility"
template <class Tag, typename T>
class strong_typedef
{
public:
strong_typedef() : value_()
{
}
explicit strong_typedef(const T& value) : value_(value)
{
}
explicit strong_typedef(T&& value) noexcept(std::is_nothrow_move_constructible<T>::value)
: value_(std::move(value))
{
}
explicit operator T&() noexcept
{
return value_;
}
explicit operator const T&() const noexcept
{
return value_;
}
friend void swap(strong_typedef& a, strong_typedef& b) noexcept
{
using std::swap;
swap(static_cast<T&>(a), static_cast<T&>(b));
}
private:
T value_;
};
template <typename Tag, typename T>
T underlying_type_impl(strong_typedef<Tag, T>);
template <typename T>
using underlying_type = decltype(underlying_type_impl(std::declval<T>()));
#endif //UNTITLED_STRONG_TYPEDEF_H
template <class StrongTypedef>
struct comparison
{
friend bool operator==(const StrongTypedef& lhs, const StrongTypedef& rhs)
{
using type = underlying_type<StrongTypedef>;
return static_cast<const type&>(lhs) == static_cast<const type&>(rhs);
}
};