-
Notifications
You must be signed in to change notification settings - Fork 6
/
generic_assign.hpp
126 lines (106 loc) · 2.99 KB
/
generic_assign.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
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/**
* @file generic_assign.hpp
* @brief
* @date 2020-6-6
* @author Peter
* @copyright
* Peter of [ThinkSpirit Laboratory](http://thinkspirit.org/)
* of [Nanjing University of Information Science & Technology](http://www.nuist.edu.cn/)
* all rights reserved
*/
#ifndef KERBAL_ASSIGN_GENERIC_ASSIGN_HPP
#define KERBAL_ASSIGN_GENERIC_ASSIGN_HPP
#include <kerbal/assign/generic_assign/generic_assign.fwd.hpp>
#include <kerbal/compatibility/constexpr.hpp>
#include <kerbal/compatibility/noexcept.hpp>
#if __cplusplus >= 201103L
# include <kerbal/compatibility/static_assert.hpp>
# include <kerbal/type_traits/extent.hpp>
# include <kerbal/type_traits/integral_constant.hpp>
# include <kerbal/type_traits/is_array.hpp>
# include <kerbal/type_traits/remove_reference.hpp>
# include <kerbal/utility/forward.hpp>
#endif
#include <cstddef>
namespace kerbal
{
namespace assign
{
template <typename T, typename U>
KERBAL_CONSTEXPR14
T & generic_assign(T & lhs, const U & rhs)
KERBAL_CONDITIONAL_NOEXCEPT(
noexcept(lhs = rhs)
)
{
lhs = rhs;
return lhs;
}
template <typename T, typename U, std::size_t N>
KERBAL_CONSTEXPR14
T (& generic_assign(T (& lhs)[N], const U (& rhs)[N]))[N]
{
for (std::size_t i = 0; i < N; ++i) {
kerbal::assign::generic_assign(lhs[i], rhs[i]);
}
return lhs;
}
# if __cplusplus >= 201103L
namespace detail
{
template <typename T, typename U>
KERBAL_CONSTEXPR14
void k_generic_assign(T & lhs, U && rhs, kerbal::type_traits::false_type)
KERBAL_CONDITIONAL_NOEXCEPT(
noexcept(lhs = kerbal::utility::forward<U>(rhs))
)
{
lhs = kerbal::utility::forward<U>(rhs);
}
template <typename T, typename U>
KERBAL_CONSTEXPR14
void k_generic_assign(T & lhs, U && rhs, kerbal::type_traits::true_type)
KERBAL_CONDITIONAL_NOEXCEPT(
noexcept(
kerbal::assign::generic_assign(
lhs[0],
kerbal::utility::forward<decltype(rhs[0])>(rhs[0])
)
)
)
{
typedef kerbal::type_traits::extent<T, 0> TP_EXTENT;
typedef kerbal::type_traits::extent<
typename kerbal::type_traits::remove_reference<U>::type, 0
> UP_EXTENT;
KERBAL_STATIC_ASSERT(TP_EXTENT::value == UP_EXTENT::value, "T and U must have same length");
for (std::size_t i = 0; i < TP_EXTENT::value; ++i) {
kerbal::assign::generic_assign(
lhs[i],
kerbal::utility::forward<decltype(rhs[i])>(rhs[i])
);
}
}
} // namespace detail
template <typename T, typename U>
KERBAL_CONSTEXPR14
T & generic_assign(T & lhs, U && rhs)
KERBAL_CONDITIONAL_NOEXCEPT(
noexcept(
kerbal::assign::detail::k_generic_assign(
lhs, kerbal::utility::forward<U>(rhs), kerbal::type_traits::is_array<T>()
)
)
)
{
kerbal::assign::detail::k_generic_assign(
lhs,
kerbal::utility::forward<U>(rhs),
kerbal::type_traits::is_array<T>()
);
return lhs;
}
# endif
} // namespace assign
} // namespace kerbal
#endif // KERBAL_ASSIGN_GENERIC_ASSIGN_HPP