|
7 | 7 | *
|
8 | 8 | * $ g++ matrix_constraint.hpp -std=c++2b -Wall -Wextra -O3 -Wno-pragma-once-outside-header
|
9 | 9 | *
|
10 |
| - * @copyright ueg (c) 2023 |
| 10 | + * @copyright Copyright (c) 2023 |
11 | 11 | *
|
12 | 12 | */
|
13 | 13 |
|
|
17 | 17 |
|
18 | 18 | #include <array>
|
19 | 19 | #include <concepts>
|
| 20 | +#include <iterator> |
| 21 | +#include <ranges> |
| 22 | +#include <vector> |
| 23 | + |
| 24 | + |
| 25 | +namespace robotics |
| 26 | +{ |
20 | 27 |
|
21 | 28 | template<typename T, std::size_t M, std::size_t N>
|
22 | 29 | concept matrix = requires (std::array<std::array<T, N>, M> matrix) {
|
23 |
| - { |
24 |
| - matrix.size() |
25 |
| - } -> std::convertible_to<size_t>; |
26 |
| - { |
27 |
| - matrix[0].size() |
28 |
| - } -> std::convertible_to<size_t>; |
| 30 | + { matrix.size() } -> std::convertible_to<size_t>; |
| 31 | + { matrix[0].size() } -> std::convertible_to<size_t>; |
| 32 | +}; |
| 33 | + |
| 34 | +template<typename R, typename T> |
| 35 | +concept weak_matrix = std::convertible_to<std::ranges::range_reference_t<std::ranges::range_reference_t<R>>, T>; |
| 36 | + |
| 37 | +template<typename T> |
| 38 | +concept random_access_container = requires (T container) { |
| 39 | + typename T::value_type; |
| 40 | + typename T::iterator; |
| 41 | + typename T::const_iterator; |
| 42 | + |
| 43 | + // check if the container has begin() and end() member functions |
| 44 | + { container.begin() } -> std::same_as<typename T::iterator>; |
| 45 | + { container.end() } -> std::same_as<typename T::iterator>; |
| 46 | + |
| 47 | + // check if the container supports random access |
| 48 | + requires std::random_access_iterator<typename T::iterator>; |
| 49 | + |
| 50 | + // check if the container has size() member function |
| 51 | + { container.size() } -> std::integral; |
| 52 | + |
| 53 | + // check if the container has the subscript operator (operator[]) |
| 54 | + requires requires (T container, typename T::size_type i) { |
| 55 | + { container[i] } -> std::same_as<typename T::reference>; |
| 56 | + }; |
29 | 57 | };
|
30 | 58 |
|
| 59 | +// Concept to constrain a 2D matrix |
| 60 | +template<typename T> |
| 61 | +concept random_access_matrix = |
| 62 | + random_access_container<T> && random_access_container<typename T::value_type> && requires (T mat) { |
| 63 | + // Optional: Add additional constraints like ensuring the matrix has |
| 64 | + // rows of equal size |
| 65 | + { mat.size() > 0 } -> std::convertible_to<bool>; |
| 66 | + { mat[0].size() > 0 } -> std::convertible_to<bool>; |
| 67 | + }; |
| 68 | + |
| 69 | +// Example usage with a vector of vectors (2D matrix) |
| 70 | +static_assert(random_access_matrix<std::vector<std::vector<int>>>); |
| 71 | + |
| 72 | +} // namespace robotics |
| 73 | + |
31 | 74 | #endif // !MATRIX_CONSTRAINT_HPP
|
0 commit comments