29 static_assert(std::is_arithmetic_v<T>);
32 using container_type =
typename std::array<T, max_size>;
33 using iterator =
typename container_type::const_iterator;
34 using const_iterator =
typename container_type::const_iterator;
37 StaticSet()
noexcept {}
39 StaticSet(std::initializer_list<T> list) {
40 for (
const auto& val : list) Insert(val);
43 bool Insert(T value) {
45 for (; i < size_; i++) {
46 if (data_[i] == value)
return false;
48 if (data_[i] > value) {
49 for (std::size_t j = size_; j > i && size_ + 1 <= max_size; j--) {
51 data_[j] = data_[j - 1];
57 if (size_ + 1 > max_size) {
68 bool Contains(T value)
const noexcept {
69 return std::find(data_.begin(), data_.begin() + size_, value) != data_.begin() + size_;
72 [[nodiscard]] StaticSet<T, max_size> Join(
const StaticSet<T, max_size>& other)
const {
73 StaticSet<T, max_size> result;
75 std::size_t i = 0, j = 0, k = 0;
78 while (i < size_ && j < other.size_ && k < max_size) {
79 if (data_[i] == other.data_[j]) {
80 result.data_[k] = data_[i];
83 }
else if (data_[i] < other.data_[j]) {
84 result.data_[k] = data_[i];
87 result.data_[k] = other.data_[j];
93 while (i < size_ && k < max_size) {
94 result.data_[k] = data_[i];
99 while (j < other.size_ && k < max_size) {
100 result.data_[k] = other.data_[j];
107 if (i != size_ || j != other.size_) {
111 assert(result.size_ >= size_ && result.size_ >= other.size_);
115 [[nodiscard]] StaticSet<T, max_size> Intersect(
const StaticSet<T, max_size>& other)
const {
116 StaticSet<T, max_size> new_set;
117 auto new_end = std::set_intersection(data_.begin(), data_.begin() + size_, other.data_.begin(),
118 other.data_.begin() + other.size_, new_set.data_.begin());
120 new_set.size_ =
static_cast<std::size_t
>(std::distance(new_set.data_.begin(), new_end));
125 [[nodiscard]] StaticSet<T, max_size> Difference(
const StaticSet<T, max_size>& other)
const {
126 StaticSet<T, max_size> new_set;
127 auto new_end = std::set_difference(data_.begin(), data_.begin() + size_, other.data_.begin(),
128 other.data_.begin() + other.size_, new_set.data_.begin());
130 new_set.size_ =
static_cast<std::size_t
>(std::distance(new_set.data_.begin(), new_end));
135 bool IsSubset(
const StaticSet<T, max_size>& other)
const {
136 if (other.Size() > Size())
return false;
138 return std::includes(data_.begin(), data_.begin() + size_, other.data_.begin(), other.data_.begin() + other.size_);
141 std::size_t Size()
const noexcept {
return size_; }
143 bool IsEmpty()
const noexcept {
return size_ == 0; }
145 void Clear()
noexcept { size_ = 0; }
147 const T& operator[](std::size_t index)
const noexcept {
152 bool operator==(
const StaticSet& rhs)
const noexcept {
153 if (rhs.Size() != Size())
return false;
155 for (std::size_t i = 0; i < rhs.Size(); i++)
156 if (data_[i] != rhs.data_[i])
return false;
161 const_iterator begin()
const noexcept {
return data_.cbegin(); }
163 const_iterator end()
const noexcept {
return data_.cbegin() + size_; }
165 const_iterator cbegin()
const noexcept {
return data_.cbegin(); }
167 const_iterator cend()
const noexcept {
return data_.cbegin() + size_; }
169 const value_type& front()
const noexcept {
171 return *data_.cbegin();
174 const value_type& back()
const noexcept {
176 return *data_.rcbegin();
180 std::size_t size_ = 0;
181 container_type data_;