SHOW:
|
|
- or go back to the newest paste.
1 | #include <type_traits> | |
2 | #include <cassert> | |
3 | #include <array> | |
4 | struct has_iterator_impl { | |
5 | template<typename T> | |
6 | static std::true_type check(typename T::iterator*); | |
7 | ||
8 | template<typename T> | |
9 | static std::false_type check(...); | |
10 | }; | |
11 | ||
12 | template<typename T> | |
13 | class has_iterator : | |
14 | public decltype(has_iterator_impl::check<T>(nullptr)) {}; | |
15 | struct has_const_iterator_impl { | |
16 | template<typename T> | |
17 | static std::true_type check(typename T::const_iterator*); | |
18 | ||
19 | template<typename T> | |
20 | static std::false_type check(...); | |
21 | }; | |
22 | ||
23 | template<typename T> | |
24 | class has_const_iterator : | |
25 | public decltype(has_iterator_impl::check<T>(nullptr)) {}; | |
26 | ||
27 | template<typename T> | |
28 | struct is_container : std::integral_constant<bool, has_const_iterator<T>::value && has_iterator<T>::value> | |
29 | { }; | |
30 | ||
31 | ||
32 | template<typename T, std::size_t N, std::enable_if_t<2 <= N, std::nullptr_t> = nullptr> | |
33 | constexpr Vec2<T> make_Vec2(const T(&arr)[N]) noexcept(std::is_nothrow_copy_constructible<T>::value){ | |
34 | return {arr[0], arr[1]}; | |
35 | } | |
36 | template<typename T, std::size_t N, std::enable_if_t<2 <= N, std::nullptr_t> = nullptr> | |
37 | constexpr Vec2<T> make_Vec2(const std::array<T, N>& arr) noexcept(std::is_nothrow_copy_constructible<T>::value){ | |
38 | return {arr[0], arr[1]}; | |
39 | } | |
40 | template<typename Container, std::enable_if_t<is_container<T>::value, std::nullptr_t> = nullptr> | |
41 | auto make_Vec2(const Container& container) -> Vec2<typename Container::value_type> noexcept(std::is_nothrow_copy_constructible<Container::value_type>::value) | |
42 | { | |
43 | assert(container.size() < 2); | |
44 | return {*(container.begin()), *std::next(container.begin(), 1)} | |
45 | } | |
46 | template<typename InputIterator> | |
47 | auto make_Vec2(InputIterator begin, InputIterator end) | |
48 | -> Vec2<decltype(*(std::declval<InputIterator>))> noexcept(std::is_nothrow_copy_constructible<*(std::declval<InputIterator>)>::value) | |
49 | { | |
50 | assert(std::distance(begin, end) < 2); | |
51 | return {*begin, *std::next(begin, 1)} | |
52 | } | |
53 | ||
54 | template<typename T, std::size_t N, std::enable_if_t<3 <= N, std::nullptr_t> = nullptr> | |
55 | constexpr Vec3<T> make_Vec3(const T(&arr)[N]) noexcept(std::is_nothrow_copy_constructible<T>::value){ | |
56 | return {arr[0], arr[1], arr[2]}; | |
57 | } | |
58 | template<typename T, std::size_t N, std::enable_if_t<3 <= N, std::nullptr_t> = nullptr> | |
59 | constexpr Vec3<T> make_Vec3(const std::array<T, N>& arr) noexcept(std::is_nothrow_copy_constructible<T>::value){ | |
60 | return {arr[0], arr[1], arr[2]}; | |
61 | } | |
62 | template<typename Container, std::enable_if_t<is_container<T>::value, std::nullptr_t> = nullptr> | |
63 | auto make_Vec3(const Container& container) -> Vec3<typename Container::value_type> noexcept(std::is_nothrow_copy_constructible<Container::value_type>::value) | |
64 | { | |
65 | assert(container.size() < 3); | |
66 | return {*(container.begin()), *std::next(container.begin(), 1), *std::next(container.begin(), 2)} | |
67 | } | |
68 | template<typename InputIterator> | |
69 | auto make_Vec3(InputIterator begin, InputIterator end) | |
70 | -> Vec3<decltype(*(std::declval<InputIterator>))> noexcept(std::is_nothrow_copy_constructible<*(std::declval<InputIterator>)>::value) | |
71 | { | |
72 | assert(std::distance(begin, end) < 3); | |
73 | return {*begin, *std::next(begin, 1), *std::next(begin, 2)} | |
74 | } |