libGimbal 0.1.0
C17-Based Extended Standard Library and Cross-Language Runtime Framework
Loading...
Searching...
No Matches
gimbal_container.hpp
1#ifndef GIMBAL_CONTAINER_HPP
2#define GIMBAL_CONTAINER_HPP
3
4#include "../types/gimbal_typedefs.hpp"
5#include "gimbal_container.h"
7#include <limits>
8#include <initializer_list>
9#include <concepts>
10#include <algorithm>
11#include <compare>
12
13namespace gbl {
14
15template<typename It, typename T>
16concept type_compatible_iterator_readable =
17 std::input_iterator<It> &&
18 requires(It it, T t) {
19 { t = *it };
20 };
21
22template<typename It, typename T>
23concept type_compatible_iterator_writable =
24 std::output_iterator<It, T>;
25
26template<typename It, typename T>
27concept type_compatible_iterator =
28 type_compatible_iterator_readable<It, T> &&
29 type_compatible_iterator_writable<It, T>;
30
31template<typename It, typename T>
32concept type_compatible_iterator_read_only =
33 type_compatible_iterator_readable<It, T> &&
34 !type_compatible_iterator_writable<It, T>;
35
36template<typename It>
37concept contiguous_iterator =
38 std::input_or_output_iterator<It> &&
39 (std::is_base_of_v<std::contiguous_iterator_tag, It> ||
40 std::is_base_of_v<gimbal::tags::RandomAccessIteratorBase, It>);
41
42template<typename It>
43concept forward_iterator =
44 std::input_or_output_iterator<It> &&
45 std::is_base_of_v<std::forward_iterator_tag, It>;
46
47template<typename C, typename T>
48concept type_compatible_container_readable =
49 requires(C c) {
50 { std::cbegin(c) } -> type_compatible_iterator_readable<T>;
51 { std::cend(c) } -> type_compatible_iterator_readable<T>;
52 };
53
54template<typename C, typename T>
55concept type_compatible_container_writable =
56 requires(C c) {
57 { std::begin(c) } -> type_compatible_iterator_writable<T>;
58 { std::end(c) } -> type_compatible_iterator_writable<T>;
59 };
60
61template<typename C, typename T>
62concept type_compatible_container =
63 type_compatible_container_readable<C, T> &&
64 type_compatible_container_writable<C, T>;
65
66template<typename C, typename T>
67concept type_compatible_container_read_only =
68 type_compatible_container_readable<C, T> &&
69 !type_compatible_container_writable<C, T>;
70
71template<typename C, typename T>
72concept type_compatible_contiguous_container_readable =
73 type_compatible_container<C, T> &&
74 requires(const C c) {
75 { c.data() } -> std::same_as<const T*>;
76 };
77
78template<typename C, typename T>
79concept type_compatible_contiguous_container_writable =
80 type_compatible_container<C, T> &&
81 requires(C c) {
82 { c.data() } -> std::same_as<T*>;
83 };
84
85template<typename C, typename T>
86concept type_compatible_contiguous_container =
87 type_compatible_contiguous_container_readable<C, T> &&
88 type_compatible_container_writable<C, T>;
89
90template<typename C, typename T>
91concept type_compatible_contiguous_container_read_only =
92 type_compatible_contiguous_container_readable<C, T> &&
93 !type_compatible_container_writable<C, T>;
94
95template<typename C>
96concept generic_container_readable =
97 requires(C c) {
98 { std::cbegin(c) } -> std::input_or_output_iterator;
99 { std::cend(c) } -> std::input_or_output_iterator;
100 };
101
102template<typename C,
103 typename T = std::decay_t<decltype(*std::begin(std::declval<C>()))>>
104struct container_value {
105 using type = T;
106};
107
108template<typename C>
109using container_value_t = typename container_value<C>::type;
110
111template<typename It,
112 typename T = std::decay_t<decltype(*(std::declval<It>()))>>
113struct iterator_value {
114 using type = T;
115};
116
117template<typename C>
118using iterator_value_t = typename iterator_value<C>::type;
119
120}
121
122#endif // GIMBAL_CONTAINER_HPP