aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/engine/data/vector2.cpp20
-rw-r--r--src/engine/data/vector2.hpp5
-rw-r--r--src/game/RLE_reader.cpp44
-rw-r--r--src/game/cell_helper.hpp9
-rw-r--r--src/game/cell_helper_impl.hpp121
-rw-r--r--src/game/components/statusline.cpp23
-rw-r--r--src/game/game.cpp86
-rw-r--r--src/game/game.hpp5
-rw-r--r--src/interfaces/cell_helper.hpp5
-rw-r--r--src/util/algorithm.hpp38
-rw-r--r--src/util/algorithm_impl.hpp67
-rw-r--r--src/util/ranges.hpp47
-rw-r--r--src/util/ranges_impl.hpp59
14 files changed, 184 insertions, 346 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 2a98dd7..147f0e0 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -64,6 +64,7 @@ target_link_libraries_system(
yacppdic
ctre
backward
+ range-v3
)
target_link_options(${PROJECT_NAME} PRIVATE -fsanitize=address)
diff --git a/src/engine/data/vector2.cpp b/src/engine/data/vector2.cpp
index 84986bd..80fc43c 100644
--- a/src/engine/data/vector2.cpp
+++ b/src/engine/data/vector2.cpp
@@ -82,11 +82,31 @@ auto Vector2::operator==(const Vector2 &rhs) const noexcept -> bool
return _x == rhs._x && _y == rhs._y;
}
+auto Vector2::operator!=(const Vector2 &rhs) const noexcept -> bool
+{
+ return !(*this == rhs);
+}
+
auto Vector2::operator<(const Vector2 &rhs) const noexcept -> bool
{
return std::tie(_x, _y) < std::tie(rhs._x, rhs._y);
}
+auto Vector2::operator>(const Vector2 &rhs) const noexcept -> bool
+{
+ return std::tie(_x, _y) > std::tie(rhs._x, rhs._y);
+}
+
+auto Vector2::operator<=(const Vector2 &rhs) const noexcept -> bool
+{
+ return *this < rhs || *this == rhs;
+}
+
+auto Vector2::operator>=(const Vector2 &rhs) const noexcept -> bool
+{
+ return *this > rhs || *this == rhs;
+}
+
auto Vector2Hasher::operator()(const Vector2 &vector2) const noexcept -> std::size_t
{
std::size_t result_hash = 0;
diff --git a/src/engine/data/vector2.hpp b/src/engine/data/vector2.hpp
index 03c2562..da96e72 100644
--- a/src/engine/data/vector2.hpp
+++ b/src/engine/data/vector2.hpp
@@ -43,8 +43,13 @@ public:
auto operator*(const Vector2 &rhs) const noexcept -> Vector2;
auto operator==(const Vector2 &rhs) const noexcept -> bool;
+ auto operator!=(const Vector2 &rhs) const noexcept -> bool;
auto operator<(const Vector2 &rhs) const noexcept -> bool;
+ auto operator>(const Vector2 &rhs) const noexcept -> bool;
+
+ auto operator<=(const Vector2 &rhs) const noexcept -> bool;
+ auto operator>=(const Vector2 &rhs) const noexcept -> bool;
/**
* Returns Vector2({.x = 0, .y = 1})
diff --git a/src/game/RLE_reader.cpp b/src/game/RLE_reader.cpp
index df2823c..79890f1 100644
--- a/src/game/RLE_reader.cpp
+++ b/src/game/RLE_reader.cpp
@@ -1,14 +1,19 @@
#include "RLE_reader.hpp"
-#include <ctre.hpp>
#include <cctype>
+#include <ctre.hpp>
+#include <range/v3/algorithm/find_if.hpp>
+#include <range/v3/algorithm/fold_left.hpp>
+#include <range/v3/range/conversion.hpp>
+#include <range/v3/view/drop.hpp>
+#include <range/v3/view/iota.hpp>
+#include <range/v3/view/join.hpp>
#include <string>
#include <vector>
#include "engine/data/bounds.hpp"
#include "engine/data/vector2.hpp"
#include "errors/RLE_reader.hpp"
-#include "util/algorithm_impl.hpp"
#include "util/io_impl.hpp"
#include "util/string_impl.hpp"
@@ -32,15 +37,14 @@ auto RLEReader::read_RLE_file(const std::filesystem::path &path) const
content_lines.pop_back();
}
- const auto header_line_iter = container_find(
+ const auto header_line_iter = ranges::find_if(
content_lines,
[](const std::string &line)
{
return ctre::starts_with<"x = \\d+, y = \\d+">(line);
- // return ctre::match<"x = \\d+, y = \\d+(, rule = [a-zA-Z0-9/]+)?">(line);
});
- if (header_line_iter == content_lines.end())
+ if (header_line_iter == ranges::end(content_lines))
{
throw InvalidRLEFileError(path, "No header line");
}
@@ -64,26 +68,28 @@ auto RLEReader::read_RLE_file(const std::filesystem::path &path) const
auto pattern_pos = Vector2({.x = 0, .y = 0});
- const auto first_pattern_line_iter = header_line_iter + 1;
+ const auto header_line_index =
+ static_cast<int32_t>(header_line_iter - content_lines.begin());
- for (auto pattern_line_iter = first_pattern_line_iter;
- pattern_line_iter != content_lines.end();
- ++pattern_line_iter)
+ const auto pattern_lines = content_lines |
+ ranges::views::drop(header_line_index + 1) |
+ ranges::to<std::vector>();
+
+ for (const auto &pattern_line : pattern_lines)
{
- if (!ctre::match<"[bo$0-9!]+">(*pattern_line_iter))
+ if (!ctre::match<"[bo$0-9!]+">(pattern_line))
{
throw InvalidRLEFileError(path, "Invalid pattern line");
}
}
- auto pattern = std::string();
-
- for (auto pattern_line_iter = first_pattern_line_iter;
- pattern_line_iter != content_lines.end();
- ++pattern_line_iter)
- {
- pattern.append(*pattern_line_iter);
- }
+ auto pattern = ranges::fold_left(
+ pattern_lines,
+ std::string(),
+ [](const std::string &acc, const std::string &line)
+ {
+ return acc + line;
+ });
auto run_count_str = std::string();
@@ -111,7 +117,7 @@ auto RLEReader::read_RLE_file(const std::filesystem::path &path) const
continue;
}
- for (auto run_index = 0; run_index < run_count; run_index++)
+ for (const auto &run_index : ranges::views::iota(0, run_count))
{
if (pattern_size.validate_coords(pattern_pos) != CoordsValidation::VALID)
{
diff --git a/src/game/cell_helper.hpp b/src/game/cell_helper.hpp
index cf84a75..c54b12e 100644
--- a/src/game/cell_helper.hpp
+++ b/src/game/cell_helper.hpp
@@ -5,7 +5,6 @@
#include "engine/data/vector2.hpp"
-#include <list>
#include <memory>
#include <vector>
@@ -19,17 +18,17 @@ public:
-> bool override;
[[nodiscard]] auto
- get_birth_cell_positions(const std::list<Vector2> &cell_positions) const noexcept
- -> std::list<Vector2> override;
+ get_birth_cell_positions(const std::vector<Vector2> &cell_positions) const noexcept
+ -> std::vector<Vector2> override;
[[nodiscard]] auto find_neighbours(const Vector2 &cell_pos) const noexcept
-> std::vector<Vector2> override;
private:
- std::shared_ptr<IMatrix<MatrixElement>> _matrix;
+ const std::shared_ptr<IMatrix<MatrixElement>> _matrix;
static auto _get_position_neighbours(const Vector2 &position) noexcept
- -> std::list<Vector2>;
+ -> std::vector<Vector2>;
};
#include "cell_helper_impl.hpp"
diff --git a/src/game/cell_helper_impl.hpp b/src/game/cell_helper_impl.hpp
index bd40794..c03b80c 100644
--- a/src/game/cell_helper_impl.hpp
+++ b/src/game/cell_helper_impl.hpp
@@ -2,18 +2,15 @@
#include "cell_helper.hpp"
-#include "util/algorithm.hpp"
-
-template <typename MatrixElement>
-constexpr auto has_matrix_value(
- const std::shared_ptr<IMatrix<MatrixElement>> &matrix,
- const MatrixElement &value) noexcept
-{
- return [&matrix, &value](const Vector2 &pos)
- {
- return matrix->get(pos) == value;
- };
-}
+#include <memory>
+#include <range/v3/action/insert.hpp>
+#include <range/v3/action/sort.hpp>
+#include <range/v3/action/unique.hpp>
+#include <range/v3/algorithm/count_if.hpp>
+#include <range/v3/algorithm/fold_left.hpp>
+#include <range/v3/range/conversion.hpp>
+#include <range/v3/view/filter.hpp>
+#include <utility>
template <typename MatrixElement>
CellHelper<MatrixElement>::CellHelper(
@@ -26,74 +23,82 @@ template <typename MatrixElement>
auto CellHelper<MatrixElement>::is_cell_dying(const Vector2 &cell_pos) const noexcept
-> bool
{
- const auto neighbour_cell_positions =
- container_filter(find_neighbours(cell_pos), has_matrix_value(_matrix, 'x'));
-
- const auto neighbour_cell_cnt = neighbour_cell_positions.size();
+ int64_t neighbour_cell_cnt = ranges::count_if(
+ find_neighbours(cell_pos),
+ [this](const Vector2 &pos)
+ {
+ return _matrix->get(pos) == 'x';
+ });
return neighbour_cell_cnt < 2 || neighbour_cell_cnt >= 4;
}
template <typename MatrixElement>
auto CellHelper<MatrixElement>::get_birth_cell_positions(
- const std::list<Vector2> &cell_positions) const noexcept -> std::list<Vector2>
+ const std::vector<Vector2> &cell_positions) const noexcept -> std::vector<Vector2>
{
- auto all_empty_neighbour_positions = std::list<Vector2>();
-
- for (const auto &cell_pos : cell_positions)
- {
- const std::vector<Vector2> empty_neighbour_positions =
- container_filter(find_neighbours(cell_pos), has_matrix_value(_matrix, ' '));
-
- all_empty_neighbour_positions.insert(
- all_empty_neighbour_positions.end(),
- empty_neighbour_positions.begin(),
- empty_neighbour_positions.end());
- }
-
- // Remove duplicates
- all_empty_neighbour_positions.sort();
- all_empty_neighbour_positions.unique();
-
- auto birth_cell_positions = container_filter(
- all_empty_neighbour_positions,
- [this](const Vector2 &cell_pos)
- {
- const auto neighbour_cell_positions = container_filter(
- find_neighbours(cell_pos),
- has_matrix_value(_matrix, 'x'));
-
- return neighbour_cell_positions.size() == 3;
- });
-
- return birth_cell_positions;
+ std::vector<Vector2> empty_neighbour_positions =
+ ranges::fold_left(
+ cell_positions,
+ std::vector<Vector2>(),
+ [this](std::vector<Vector2> acc, const Vector2 &pos)
+ {
+ std::vector<Vector2> neighbours = find_neighbours(pos);
+
+ auto empty_neighbours =
+ neighbours | ranges::views::filter(
+ [this](const Vector2 &neighbour_pos)
+ {
+ return _matrix->get(neighbour_pos) == ' ';
+ });
+
+ ranges::actions::insert(acc, acc.end(), empty_neighbours);
+
+ return acc;
+ }) |
+ ranges::actions::sort | ranges::actions::unique;
+
+ auto birth_cell_positions = empty_neighbour_positions |
+ ranges::views::filter(
+ [this](const Vector2 &cell_pos)
+ {
+ auto neighbours = find_neighbours(cell_pos);
+
+ int64_t neighbour_cell_cnt = ranges::count_if(
+ neighbours,
+ [this](const Vector2 &neighbour_pos)
+ {
+ return _matrix->get(neighbour_pos) == 'x';
+ });
+
+ return neighbour_cell_cnt == 3;
+ });
+
+ return birth_cell_positions | ranges::to<std::vector>();
}
template <typename MatrixElement>
auto CellHelper<MatrixElement>::find_neighbours(const Vector2 &cell_pos) const noexcept
-> std::vector<Vector2>
{
- std::vector<Vector2> cell_positions = {};
-
const auto matrix_size =
Bounds({.width = _matrix->get_column_cnt(), .height = _matrix->get_row_cnt()});
const auto neighbours = _get_position_neighbours(cell_pos);
- for (const auto &neighbour_pos : neighbours)
- {
- if (matrix_size.validate_coords(neighbour_pos) == CoordsValidation::VALID)
- {
- cell_positions.push_back(neighbour_pos);
- }
- }
-
- return cell_positions;
+ return neighbours |
+ ranges::views::filter(
+ [&matrix_size](const Vector2 &neighbour_pos)
+ {
+ return matrix_size.validate_coords(neighbour_pos) ==
+ CoordsValidation::VALID;
+ }) |
+ ranges::to<std::vector>();
}
template <typename MatrixElement>
auto CellHelper<MatrixElement>::_get_position_neighbours(const Vector2 &position) noexcept
- -> std::list<Vector2>
+ -> std::vector<Vector2>
{
return {
position + Vector2::up(),
diff --git a/src/game/components/statusline.cpp b/src/game/components/statusline.cpp
index aac1c27..8344c22 100644
--- a/src/game/components/statusline.cpp
+++ b/src/game/components/statusline.cpp
@@ -1,12 +1,11 @@
#include "statusline.hpp"
#include <fmt/color.h>
+#include <range/v3/view/iota.hpp>
#include <utility>
#include "engine/data/vector2.hpp"
#include "interfaces/matrix.hpp"
-#include "util/ranges.hpp"
-#include "util/ranges_impl.hpp"
StatusLine::StatusLine(std::shared_ptr<ComponentMatrix> component_matrix) noexcept
: _component_matrix(std::move(component_matrix)), _need_render(false)
@@ -55,7 +54,8 @@ void StatusLine::set_section_status(
auto pos = Vector2({.x = section_start + start, .y = 0});
- const auto column_cnt = static_cast<std::int32_t>(_component_matrix->get_column_cnt());
+ const auto column_cnt =
+ static_cast<std::int32_t>(_component_matrix->get_column_cnt());
const auto section_length = _section_lengths[section];
@@ -73,7 +73,7 @@ void StatusLine::set_section_status(
_component_matrix->set(pos, {.value = ' ', .style = section_style});
padding_remaining--;
- for (auto index : IotaView(0U, padding_remaining))
+ for (auto index : ranges::views::iota(0U, padding_remaining))
{
pos += Vector2::right();
@@ -103,11 +103,13 @@ void StatusLine::set_section_status(
_matrix_write_string(
pos,
- status.substr(status_offset_start, static_cast<std::uint32_t>(final_status_length)));
+ status.substr(
+ status_offset_start,
+ static_cast<std::uint32_t>(final_status_length)));
pos = pos.to_direction(Vector2::right(), final_status_length);
- for (auto index : IotaView(0U, section_style.padding_right))
+ for (auto index : ranges::views::iota(0U, section_style.padding_right))
{
_component_matrix->set(pos, {.value = ' '});
@@ -119,7 +121,9 @@ void StatusLine::set_section_status(
set_need_render(true);
}
-void StatusLine::set_section_length(StatusLineSection section, std::int32_t length) noexcept
+void StatusLine::set_section_length(
+ StatusLineSection section,
+ std::int32_t length) noexcept
{
_section_lengths[section] = length;
}
@@ -143,7 +147,8 @@ void StatusLine::_matrix_write_string(
}
}
-auto StatusLine::_get_section_start_x(StatusLineSection section) const noexcept -> std::int32_t
+auto StatusLine::_get_section_start_x(StatusLineSection section) const noexcept
+ -> std::int32_t
{
std::int32_t section_start = 0;
@@ -169,7 +174,7 @@ void StatusLine::_clear_section(StatusLineSection section, std::int32_t start) n
auto section_length = _section_lengths[section];
- for (auto index : IotaView(0, section_length - start))
+ for (auto index : ranges::views::iota(0, section_length - start))
{
_component_matrix->set(pos, ComponentElement({.value = ' '}));
diff --git a/src/game/game.cpp b/src/game/game.cpp
index a121089..86b6eac 100644
--- a/src/game/game.cpp
+++ b/src/game/game.cpp
@@ -1,20 +1,23 @@
#include "game.hpp"
+#include <cstdlib>
+#include <filesystem>
#include <fmt/color.h>
#include <fmt/core.h>
#include <fmt/format.h>
-#include <yacppdic/factory.hpp>
-#include <cstdlib>
-#include <filesystem>
#include <iostream>
#include <iterator>
+#include <range/v3/action/remove.hpp>
+#include <range/v3/algorithm/contains.hpp>
+#include <range/v3/range/conversion.hpp>
+#include <range/v3/view/filter.hpp>
#include <stdexcept>
#include <utility>
+#include <yacppdic/factory.hpp>
#include "engine/data/bounds.hpp"
#include "engine/escape.hpp"
#include "engine/graphics/matrix_iterator.hpp"
-#include "engine/graphics/matrix_iterator_impl.hpp"
#include "engine/keycodes.hpp"
#include "errors/RLE_reader.hpp"
#include "errors/io.hpp"
@@ -24,9 +27,8 @@
#include "interfaces/input.hpp"
#include "interfaces/matrix.hpp"
#include "interfaces/status_manager.hpp"
-#include "util/algorithm_impl.hpp"
#include "util/fs.hpp"
-#include "util/string_impl.hpp"
+#include "util/string.hpp"
Game::Game(
IStatusLineFactory statusline_factory,
@@ -190,7 +192,7 @@ void Game::on_start()
scene_matrix->set(col_pos, col);
- if (!container_has(_living_cell_positions, col_pos))
+ if (!ranges::contains(_living_cell_positions, col_pos))
{
_living_cell_positions.push_back(col_pos);
}
@@ -311,7 +313,7 @@ void Game::_on_normal_mode_update() noexcept
}
_set_space(matrix, position, ' ');
- _living_cell_positions.remove(position);
+ std::erase(_living_cell_positions, position);
break;
}
@@ -390,38 +392,7 @@ void Game::_on_normal_mode_update() noexcept
_last_gen_update_time = time_now;
- auto matrix = _scene->get_matrix();
-
- const auto dying_cell_positions = container_filter(
- _living_cell_positions,
- [this](const Vector2 &cell_pos)
- {
- return _cell_helper->is_cell_dying(cell_pos);
- });
-
- auto birth_cell_positions =
- _cell_helper->get_birth_cell_positions(_living_cell_positions);
-
- for (const auto &dying_cell_pos : dying_cell_positions)
- {
- _set_space(matrix, dying_cell_pos, ' ');
-
- const auto cell_found = container_find(_living_cell_positions, dying_cell_pos);
-
- if (cell_found != _living_cell_positions.end())
- {
- _living_cell_positions.erase(cell_found);
- }
- }
-
- for (const auto &birth_cell_pos : birth_cell_positions)
- {
- if (birth_cell_pos.get_y() >= _minimum_cursor_pos_y)
- {
- _set_space(matrix, birth_cell_pos, 'x');
- _living_cell_positions.push_back(birth_cell_pos);
- }
- }
+ _process_next_generation();
}
void Game::_on_command_mode_update() noexcept
@@ -640,3 +611,38 @@ void Game::_erase_line_from_cursor() noexcept
std::cout.flush();
}
+void Game::_process_next_generation() noexcept
+{
+ const auto dying_cell_positions =
+ _living_cell_positions |
+ ranges::views::filter(
+ [this](const Vector2 &cell_pos)
+ {
+ return _cell_helper->is_cell_dying(cell_pos);
+ }) |
+ ranges::to<std::vector>();
+
+ auto birth_cell_positions =
+ _cell_helper->get_birth_cell_positions(_living_cell_positions);
+
+ auto matrix = _scene->get_matrix();
+
+ for (const auto &dying_cell_pos : dying_cell_positions)
+ {
+ _set_space(matrix, dying_cell_pos, ' ');
+
+ if (ranges::contains(_living_cell_positions, dying_cell_pos))
+ {
+ ranges::actions::remove(_living_cell_positions, dying_cell_pos);
+ }
+ }
+
+ for (const auto &birth_cell_pos : birth_cell_positions)
+ {
+ if (birth_cell_pos.get_y() >= _minimum_cursor_pos_y)
+ {
+ _set_space(matrix, birth_cell_pos, 'x');
+ _living_cell_positions.push_back(birth_cell_pos);
+ }
+ }
+}
diff --git a/src/game/game.hpp b/src/game/game.hpp
index 13e229e..9fc5237 100644
--- a/src/game/game.hpp
+++ b/src/game/game.hpp
@@ -29,6 +29,7 @@ class IGenerationTracker;
class IRLEReader;
class IStatusManager;
class IUserInputObserver;
+
template <typename ElementType>
class IMatrix;
@@ -107,7 +108,7 @@ private:
std::int64_t _generations_per_second = DEFAULT_GENERATIONS_PER_SECOND;
- std::list<Vector2> _living_cell_positions;
+ std::vector<Vector2> _living_cell_positions;
void _on_normal_mode_update() noexcept;
@@ -129,4 +130,6 @@ private:
static void _erase_entire_line() noexcept;
static void _erase_line_from_cursor() noexcept;
+
+ void _process_next_generation() noexcept;
};
diff --git a/src/interfaces/cell_helper.hpp b/src/interfaces/cell_helper.hpp
index 69bf8b0..38e214d 100644
--- a/src/interfaces/cell_helper.hpp
+++ b/src/interfaces/cell_helper.hpp
@@ -6,7 +6,6 @@
#include <yacppdic/factory.hpp>
-#include <list>
#include <memory>
#include <vector>
@@ -20,8 +19,8 @@ public:
-> bool = 0;
[[nodiscard]] virtual auto
- get_birth_cell_positions(const std::list<Vector2> &cell_positions) const noexcept
- -> std::list<Vector2> = 0;
+ get_birth_cell_positions(const std::vector<Vector2> &cell_positions) const noexcept
+ -> std::vector<Vector2> = 0;
[[nodiscard]] virtual auto find_neighbours(const Vector2 &cell_pos) const noexcept
-> std::vector<Vector2> = 0;
diff --git a/src/util/algorithm.hpp b/src/util/algorithm.hpp
deleted file mode 100644
index 60c68e2..0000000
--- a/src/util/algorithm.hpp
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma once
-
-#include "util/concepts.hpp"
-
-#include <concepts>
-
-template <typename ContainerType, typename Value>
-requires Container<ContainerType>
-constexpr auto container_find(const ContainerType &container, const Value &value) noexcept
- -> typename ContainerType::const_iterator;
-
-template <typename ContainerType, typename Predicate>
-requires Container<ContainerType> &&
- std::predicate<Predicate, typename ContainerType::value_type>
-constexpr auto
-container_find(const ContainerType &container, Predicate predicate) noexcept ->
- typename ContainerType::const_iterator;
-
-template <typename ContainerType, typename Value>
-requires Container<ContainerType>
-constexpr auto container_has(const ContainerType &container, const Value &value) noexcept
- -> bool;
-
-template <typename ContainerType, typename Predicate>
-requires Container<ContainerType> && HasPushBack<ContainerType> &&
- std::predicate<Predicate, typename ContainerType::value_type>
-constexpr auto
-container_filter(const ContainerType &container, Predicate predicate) noexcept
- -> ContainerType;
-
-template <typename ContainerType, typename Predicate>
-requires Container<ContainerType> &&
- std::predicate<Predicate, typename ContainerType::value_type>
-constexpr auto
-container_filter(const ContainerType &container, Predicate predicate) noexcept
- -> ContainerType;
-
-#include "algorithm_impl.hpp"
diff --git a/src/util/algorithm_impl.hpp b/src/util/algorithm_impl.hpp
deleted file mode 100644
index d7c5e3b..0000000
--- a/src/util/algorithm_impl.hpp
+++ /dev/null
@@ -1,67 +0,0 @@
-#pragma once
-
-#include "algorithm.hpp"
-
-#include <algorithm>
-
-template <typename ContainerType, typename Value>
-requires Container<ContainerType>
-constexpr auto container_find(const ContainerType &container, const Value &value) noexcept
- -> typename ContainerType::const_iterator
-{
- return std::find(container.begin(), container.end(), value);
-}
-
-template <typename ContainerType, typename Predicate>
-requires Container<ContainerType> &&
- std::predicate<Predicate, typename ContainerType::value_type>
-constexpr auto
-container_find(const ContainerType &container, Predicate predicate) noexcept ->
- typename ContainerType::const_iterator
-{
- return std::find_if(container.begin(), container.end(), predicate);
-}
-
-template <typename ContainerType, typename Value>
-requires Container<ContainerType>
-constexpr auto container_has(const ContainerType &container, const Value &value) noexcept
- -> bool
-{
- return container_find(container, value) != container.end();
-}
-
-template <typename ContainerType, typename Predicate>
-requires Container<ContainerType> && HasPushBack<ContainerType> &&
- std::predicate<Predicate, typename ContainerType::value_type>
-constexpr auto
-container_filter(const ContainerType &container, Predicate predicate) noexcept
- -> ContainerType
-{
- ContainerType filtered_container;
-
- std::copy_if(
- std::begin(container),
- std::end(container),
- std::back_inserter(filtered_container),
- predicate);
-
- return filtered_container;
-}
-
-template <typename ContainerType, typename Predicate>
-requires Container<ContainerType> &&
- std::predicate<Predicate, typename ContainerType::value_type>
-constexpr auto
-container_filter(const ContainerType &container, Predicate predicate) noexcept
- -> ContainerType
-{
- ContainerType filtered_container;
-
- std::copy_if(
- std::begin(container),
- std::end(container),
- std::inserter(filtered_container, filtered_container.begin()),
- predicate);
-
- return filtered_container;
-}
diff --git a/src/util/ranges.hpp b/src/util/ranges.hpp
deleted file mode 100644
index c47c7b5..0000000
--- a/src/util/ranges.hpp
+++ /dev/null
@@ -1,47 +0,0 @@
-#pragma once
-
-#include <concepts>
-#include <iterator>
-
-template <std::weakly_incrementable Value>
-class IotaViewIterator
-{
-public:
- constexpr explicit IotaViewIterator(Value value) noexcept;
-
- constexpr auto operator++() noexcept -> const IotaViewIterator &;
- constexpr auto operator++(int) noexcept -> IotaViewIterator;
-
- constexpr auto operator*() const noexcept -> Value;
-
- constexpr auto operator==(const IotaViewIterator &rhs) const noexcept -> bool;
- constexpr auto operator!=(const IotaViewIterator &rhs) const noexcept -> bool;
-
-private:
- Value _value;
-};
-
-/**
- * A range factory that generates a sequence of elements by repeatedly incrementing an
- * initial value.
- *
- * This class was created because C++20 ranges is a complete shitshow in Clang.
- * https://github.com/llvm/llvm-project/issues/52696
- */
-template <std::weakly_incrementable Value, std::semiregular Bound>
-requires std::equality_comparable_with<Value, Bound> && std::copyable<Value>
-class IotaView
-{
-public:
- constexpr IotaView(Value value, Bound bound) noexcept;
-
- [[nodiscard]] constexpr auto begin() const noexcept -> IotaViewIterator<Value>;
-
- [[nodiscard]] constexpr auto end() const noexcept -> IotaViewIterator<Value>;
-
-private:
- Value _value;
- Bound _bound;
-};
-
-#include "ranges_impl.hpp"
diff --git a/src/util/ranges_impl.hpp b/src/util/ranges_impl.hpp
deleted file mode 100644
index 1f1a577..0000000
--- a/src/util/ranges_impl.hpp
+++ /dev/null
@@ -1,59 +0,0 @@
-#pragma once
-
-#include "ranges.hpp"
-
-// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
-#define IOTA_VIEW_ITERATOR(return_type) \
- template <std::weakly_incrementable Value> \
- constexpr return_type IotaViewIterator<Value>
-
-IOTA_VIEW_ITERATOR()::IotaViewIterator(Value value) noexcept : _value(value) {}
-
-IOTA_VIEW_ITERATOR(auto)::operator++() noexcept -> const IotaViewIterator &
-{
- ++_value;
-
- return *this;
-}
-
-IOTA_VIEW_ITERATOR(auto)::operator++(int) noexcept -> IotaViewIterator
-{
- auto copy = *this;
-
- ++(*this);
-
- return copy;
-}
-
-IOTA_VIEW_ITERATOR(auto)::operator*() const noexcept -> Value
-{
- return _value;
-}
-
-IOTA_VIEW_ITERATOR(auto)::operator==(const IotaViewIterator &rhs) const noexcept -> bool
-{
- return _value == rhs._value;
-}
-
-IOTA_VIEW_ITERATOR(auto)::operator!=(const IotaViewIterator &rhs) const noexcept -> bool
-{
- return !(*this == rhs);
-}
-
-// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
-#define IOTA_VIEW(return_type) \
- template <std::weakly_incrementable Value, std::semiregular Bound> \
- requires std::equality_comparable_with<Value, Bound> && std::copyable<Value> \
- constexpr return_type IotaView<Value, Bound>
-
-IOTA_VIEW()::IotaView(Value value, Bound bound) noexcept : _value(value), _bound(bound) {}
-
-IOTA_VIEW(auto)::begin() const noexcept -> IotaViewIterator<Value>
-{
- return IotaViewIterator(_value);
-}
-
-IOTA_VIEW(auto)::end() const noexcept -> IotaViewIterator<Value>
-{
- return IotaViewIterator(_bound);
-}