end concepts examples

This commit is contained in:
2025-09-05 18:29:24 +03:00
parent 5c46e0d889
commit c91e2c08d6
3 changed files with 167 additions and 232 deletions

View File

@@ -54,244 +54,179 @@ void example_has_allocator_type(const T& container)
hack::log()("Allocator obtained successfully"); hack::log()("Allocator obtained successfully");
} }
// template<hack::concepts::modern::is_string T> template<hack::concepts::modern::is_string T>
// void example_is_string(const T& str) { void example_is_string(const T& str)
// std::cout << "String content: " << str << " (length: " << str.length() << ")" << std::endl; {
// } hack::log()("String content: ", str, " (length: ", str.length(), ")");
// }
// template<hack::concepts::modern::is_sequence_container T>
// void example_is_sequence_container(const T& container) { template<hack::concepts::modern::is_sequence_container T>
// std::cout << "Sequence container with " << container.size() << " elements" << std::endl; void example_is_sequence_container(const T& container)
// } {
// hack::log()("Sequence container with ", container.size(), " elements");
// template<hack::concepts::modern::is_random_access_container T> }
// void example_is_random_access_container(T& container) {
// if (!container.empty()) { template<hack::concepts::modern::is_random_access_container T>
// std::cout << "First element: " << container[0] << std::endl; void example_is_random_access_container(T& container)
// } {
// } if (!container.empty())
// hack::log()("First element: ", container[0]);
// template<hack::concepts::modern::is_container_adapter T> }
// void example_is_container_adapter(T& adapter) {
// std::cout << "Container adapter with " << adapter.size() << " elements" << std::endl; template<hack::concepts::modern::is_container_adapter T>
// } void example_is_container_adapter(T& adapter)
// {
// template<hack::concepts::modern::is_associative_container T> hack::log()("Container adapter with ", adapter.size(), " elements");
// void example_is_associative_container(const T& container) { }
// std::cout << "Associative container with " << container.size() << " elements" << std::endl;
// } template<hack::concepts::modern::is_associative_container T>
// void example_is_associative_container(const T& container)
// template<hack::concepts::modern::is_unordered_associative_container T> {
// void example_is_unordered_associative_container(const T& container) { hack::log()("Associative container with ", container.size(), " elements");
// std::cout << "Unordered associative container with " << container.size() << " elements" << std::endl; }
// }
// template<hack::concepts::modern::is_unordered_associative_container T>
// template<hack::concepts::modern::is_tuple_like T> void example_is_unordered_associative_container(const T& container)
// void example_is_tuple_like(const T& tuple) { {
// std::cout << "Tuple-like with " << std::tuple_size_v<T> << " elements" << std::endl; hack::log()("Unordered associative container with ", container.size(), " elements");
// } }
//
// template<hack::concepts::modern::is_fixed_array T> template<hack::concepts::modern::is_tuple_like T>
// void example_is_fixed_array(const T& array) { void example_is_tuple_like(const T& tuple)
// std::cout << "Fixed array with " << std::extent_v<T> << " elements" << std::endl; {
// } hack::log()("Tuple-like with ", std::tuple_size_v<T>, " elements");
// }
// template<hack::concepts::modern::is_std_array<T, std::tuple_size_v<T>> T>
// void example_is_std_array(const T& array) { template<hack::concepts::modern::is_fixed_array T>
// std::cout << "std::array with " << array.size() << " elements" << std::endl; void example_is_fixed_array(const T& array)
// } {
// hack::log()("Fixed array with ", std::extent_v<T>, " elements");
// template<hack::concepts::modern::is_any_container T> }
// void example_is_any_container(const T& container) {
// std::cout << "Any container with " << container.size() << " elements" << std::endl; template<hack::concepts::modern::is_std_array T>
// } void example_is_std_array(const T& array)
// {
// template<hack::concepts::modern::is_iterable T> hack::log()("std::array with ", array.size(), " elements");
// void example_is_iterable(const T& iterable) { }
// std::cout << "Iterable object: ";
// for (const auto& item : iterable) { template<hack::concepts::modern::is_any_container T>
// std::cout << item << " "; void example_is_any_container(const T& container)
// } {
// std::cout << std::endl; hack::log()("Any container with ", container.size(), " elements");
// } }
//
// template<hack::concepts::modern::is_sized T> template<hack::concepts::modern::is_iterable T>
// void example_is_sized(const T& sized) { void example_is_iterable(const T& iterable)
// if constexpr (hack::concepts::modern::has_size<T>) { {
// std::cout << "Sized object: " << sized.size() << " elements" << std::endl; hack::log()("Iterable object");
// } else { }
// std::cout << "Sized object (compile-time size)" << std::endl;
// } template<hack::concepts::modern::is_sized T>
// } void example_is_sized(const T& sized)
// {
// template<hack::concepts::modern::has_key_value_semantics T> if constexpr (hack::concepts::modern::has_size<T>)
// void example_has_key_value_semantics(T& container) { hack::log()("Sized object: ", sized.size(), " elements");
// if constexpr (hack::concepts::modern::has_mapped_type<T>) { else
// std::cout << "Key-value container, sample access demonstrated" << std::endl; hack::log()("Sized object (compile-time size)");
// } else { }
// std::cout << "Set-like container" << std::endl;
// } template<typename T>
// } void check_support(const T& value)
// {
// template<hack::concepts::modern::is_contiguous_container T> if constexpr (hack::concepts::modern::not_supported<T>)
// void example_is_contiguous_container(const T& container) { hack::log()("Type is NOT supported by this library");
// std::cout << "Contiguous memory container" << std::endl; else
// } hack::log()("Type is supported");
// }
// template<hack::concepts::modern::can_emplace<std::vector<int>, int> Container>
// void example_can_emplace(Container& container, int value) { template<hack::concepts::modern::has_key_value_semantics T>
// container.emplace_back(value); void example_has_key_value_semantics(T& container)
// std::cout << "Emplaced value: " << value << std::endl; {
// } if constexpr (hack::concepts::modern::has_mapped_type<T>)
// hack::log()("Key-value container, sample access demonstrated");
// template<hack::concepts::modern::can_push_back<std::vector<int>, int> Container> else
// void example_can_push_back(Container& container, int value) { hack::log()("Set-like container");
// container.push_back(value); }
// std::cout << "Pushed back value: " << value << std::endl;
// } template<hack::concepts::modern::is_contiguous_container T>
// void example_is_contiguous_container(const T& container)
// template<hack::concepts::modern::can_push_front<std::list<int>, int> Container> {
// void example_can_push_front(Container& container, int value) { hack::log()("Contiguous memory container");
// container.push_front(value); }
// std::cout << "Pushed front value: " << value << std::endl;
// } template<typename Container, typename Value>
// requires hack::concepts::modern::can_push_front<Container, Value>
// template<hack::concepts::modern::can_find<std::set<int>, int> Container> void example_can_push_front(Container& container, Value&& value)
// void example_can_find(Container& container, int value) { {
// auto it = container.find(value); container.push_front(std::forward<Value>(value));
// if (it != container.end()) { hack::log()("Pushed front value: ", value);
// std::cout << "Found value: " << value << std::endl; }
// } else {
// std::cout << "Value not found: " << value << std::endl; template<typename Container, typename Value>
// } requires hack::concepts::modern::can_push_back<Container, Value>
// } void example_can_push_back(Container& container, Value&& value)
// {
// // Функция для демонстрации not_supported container.push_back(std::forward<Value>(value));
// template<typename T> hack::log()("Pushed back value: ", value);
// void check_support(const T& value) { }
// if constexpr (modern::concepts::not_supported<T>) {
// std::cout << "Type is NOT supported by this library" << std::endl; template<typename Container, typename Key>
// } else { requires hack::concepts::modern::can_find<Container, Key>
// std::cout << "Type is supported" << std::endl; void example_can_find(Container& container, Key&& key)
// } {
// } auto it = container.find(std::forward<Key>(key));
if (it != container.end())
hack::log()("Found value: ", *it);
else
hack::log()("Value not found: ", key);
}
auto main(int argc, char *argv[]) -> int auto main(int argc, char *argv[]) -> int
{ {
// Базовые концепты
std::vector<int> vec = { 1, 2, 3 }; std::vector<int> vec = { 1, 2, 3 };
std::map<int, std::string> map = {{ 1, "one" }, { 2, "two" }}; std::map<int, std::string> map = {{ 1, "one" }, { 2, "two" }};
std::set<int> set = { 5, 3, 1, 4, 2 }; std::set<int> set = { 5, 3, 1, 4, 2 };
std::unordered_map<int, std::string> umap = {{ 1, "uno" }, { 2, "dos" }}; std::unordered_map<int, std::string> umap = {{ 1, "uno" }, { 2, "dos" }};
std::list<double> list = { 1.1, 2.2, 3.3 };
std::deque<char> deque = { 'a', 'b', 'c' };
std::stack<int> stack; stack.push(1); stack.push(2);
std::string str = "Hello";
std::tuple<int, std::string, double> tuple = {1, "test", 3.14};
int fixed_array[5] = {1, 2, 3, 4, 5};
std::array<float, 3> std_array = {1.0f, 2.0f, 3.0f};
int a = 10; int a = 10;
struct custom_type { int x; };
custom_type custom;
hack::log()("has_value_type:");
example_has_value_type(vec); example_has_value_type(vec);
// example_has_value_type(a); // выдаст ошибку т.к. у a нет встроенного value_type // example_has_value_type(a); // выдаст ошибку т.к. у a нет встроенного value_type
hack::log()("has_key_type:");
example_has_key_type(map); example_has_key_type(map);
hack::log()("has_mapped_type:");
example_has_mapped_type(map); example_has_mapped_type(map);
// example_has_mapped_type(set); // выдаст ошибку т.к. у set нет типа mapped_type. Этот тип характерен для контейнеров, которые хранят пары "ключ-значение". // example_has_mapped_type(set); // выдаст ошибку т.к. у set нет типа mapped_type. Этот тип характерен для контейнеров, которые хранят пары "ключ-значение".
hack::log()("has_iterator:");
example_has_iterator(vec); example_has_iterator(vec);
hack::log()("has_size:");
example_has_size(vec); example_has_size(vec);
hack::log()("has_key_compare:");
example_has_key_compare(map); example_has_key_compare(map);
hack::log()("has_allocator_type:");
example_has_allocator_type(map); example_has_allocator_type(map);
example_is_string(str);
// // Строки и контейнеры example_is_sequence_container(vec);
// std::string str = "Hello"; example_is_sequence_container(list);
// std::list<double> list = {1.1, 2.2, 3.3}; example_is_random_access_container(vec);
// std::deque<char> deque = {'a', 'b', 'c'}; example_is_container_adapter(stack);
// example_is_associative_container(set);
// std::cout << "6. is_string: "; example_is_unordered_associative_container(umap);
// example_is_string(str); example_is_tuple_like(tuple);
// example_is_fixed_array(fixed_array);
// std::cout << "7. is_sequence_container (vector): "; example_is_std_array(std_array);
// example_is_sequence_container(vec); example_is_any_container(vec);
// example_is_iterable(vec);
// std::cout << "8. is_sequence_container (list): "; example_is_sized(vec);
// example_is_sequence_container(list); check_support(a);
// check_support(custom);
// std::cout << "9. is_random_access_container: "; example_has_key_value_semantics(map);
// example_is_random_access_container(vec); example_is_contiguous_container(vec);
// example_can_push_front(list, 0);
// // Адаптеры и ассоциативные контейнеры example_can_push_back(vec, 99);
// std::stack<int> stack; example_can_find(set, 3);
// stack.push(1); stack.push(2);
//
// std::cout << "10. is_container_adapter: ";
// example_is_container_adapter(stack);
//
// std::cout << "11. is_associative_container: ";
// example_is_associative_container(set);
//
// std::cout << "12. is_unordered_associative_container: ";
// example_is_unordered_associative_container(umap);
//
// // Кортежи и массивы
// std::tuple<int, std::string, double> tuple = {1, "test", 3.14};
// int fixed_array[5] = {1, 2, 3, 4, 5};
// std::array<float, 3> std_array = {1.0f, 2.0f, 3.0f};
//
// std::cout << "13. is_tuple_like: ";
// example_is_tuple_like(tuple);
//
// std::cout << "14. is_fixed_array: ";
// example_is_fixed_array(fixed_array);
//
// std::cout << "15. is_std_array: ";
// example_is_std_array(std_array);
//
// // Универсальные концепты
// std::cout << "16. is_any_container: ";
// example_is_any_container(vec);
//
// std::cout << "17. is_iterable: ";
// example_is_iterable(vec);
//
// std::cout << "18. is_sized: ";
// example_is_sized(vec);
//
// std::cout << "19. has_key_value_semantics: ";
// example_has_key_value_semantics(map);
//
// std::cout << "20. is_contiguous_container: ";
// example_is_contiguous_container(vec);
//
// // Концепты для алгоритмов
// std::cout << "21. can_emplace: ";
// example_can_emplace(vec, 42);
//
// std::cout << "22. can_push_back: ";
// example_can_push_back(vec, 99);
//
// std::cout << "23. can_push_front: ";
// example_can_push_front(list, 0);
//
// std::cout << "24. can_find: ";
// example_can_find(set, 3);
//
// // Проверка неподдерживаемых типов
// struct CustomType { int x; };
// CustomType custom;
//
// std::cout << "25. not_supported check (int): ";
// check_support(42);
//
// std::cout << "26. not_supported check (CustomType): ";
// check_support(custom);
//
// std::cout << "\n=== Все примеры выполнены ===" << std::endl;
return 0; return 0;
} }

View File

@@ -204,8 +204,12 @@ namespace hack::concepts::modern
// @brief Проверяет, является ли тип std::array // @brief Проверяет, является ли тип std::array
// @details Обнаруживает std::array с конкретным размером // @details Обнаруживает std::array с конкретным размером
// Полезно для алгоритмов, которые требуют знания размера на этапе компиляции // Полезно для алгоритмов, которые требуют знания размера на этапе компиляции
template<typename T, std::size_t N> template<typename T>
concept is_std_array = std::same_as<T, std::array<typename T::value_type, N>>; concept is_std_array = requires(T arr) {
requires std::same_as<T, std::array<typename T::value_type, std::tuple_size_v<T>>>;
arr.size();
arr[0];
};
// Универсальные концепты для категоризации // Универсальные концепты для категоризации
// @brief Проверяет, является ли тип любым контейнером // @brief Проверяет, является ли тип любым контейнером
@@ -221,7 +225,7 @@ namespace hack::concepts::modern
is_unordered_associative_container<T> || is_unordered_associative_container<T> ||
is_container_adapter<T> || is_container_adapter<T> ||
is_fixed_array<T> || is_fixed_array<T> ||
is_std_array<T, std::tuple_size_v<T>>; is_std_array<T>;
// @brief Проверяет, является ли тип итерируемым // @brief Проверяет, является ли тип итерируемым
// @details Обнаруживает любые типы, по которым можно итерироваться: // @details Обнаруживает любые типы, по которым можно итерироваться:
@@ -276,15 +280,7 @@ namespace hack::concepts::modern
template<typename T> template<typename T>
concept is_contiguous_container = std::same_as<T, std::vector<typename T::value_type, typename T::allocator_type>> || concept is_contiguous_container = std::same_as<T, std::vector<typename T::value_type, typename T::allocator_type>> ||
is_fixed_array<T> || is_fixed_array<T> ||
is_std_array<T, std::tuple_size_v<T>>; is_std_array<T>;
// Концепты для алгоритмов
// @brief Проверяет, поддерживает ли контейнер emplace-операцию
// @details Обнаруживает контейнеры, которые могут создавать элементы на месте:
// - vector::emplace_back(), map::emplace(), etc.
// Позволяет избежать лишних копирований и перемещений
template<typename Container, typename Value>
concept can_emplace = requires(Container c, Value&& v) { c.emplace(std::forward<Value>(v)); };
// @brief Проверяет, поддерживает ли контейнер добавление в начало // @brief Проверяет, поддерживает ли контейнер добавление в начало
// @details Обнаруживает контейнеры с push_front(): // @details Обнаруживает контейнеры с push_front():

View File

@@ -10,6 +10,10 @@
#include "hack/patterns/ring_buffer.hpp" #include "hack/patterns/ring_buffer.hpp"
// HERE
// и нужно сделать реализацию где выводлится все в одной линии но при помощи цикла
// типа такого:
// for (auto i : range) hack::log(hack::log::line)(i);
namespace hack namespace hack
{ {
class log class log