#include "hack/concepts/concepts.hpp" #include "hack/logger/logger.hpp" template void example_has_value_type(const T& container) { /* typeid().name() - возвращает декорированное (mangled) имя типа, которое зависит от компилятора: i = int (в GCC/G++) d = double f = float c = char Ss = std::string (в GCC) NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE = тоже std::string (полное декорированное имя) */ hack::log()("Value type: ", typeid(typename T::value_type).name()); } template void example_has_key_type(const T& container) { hack::log()("Key type: ", typeid(typename T::key_type).name()); } template void example_has_mapped_type(const T& container) { hack::log()("Mapped type: ", typeid(typename T::mapped_type).name()); } template void example_has_iterator(const T& container) { hack::log()("Container is iterable, size: ", std::distance(container.begin(), container.end())); } template void example_has_size(const T& container) { hack::log()("Container size:", container.size()); } template void example_has_key_compare(const T& container) { hack::log()("Key compare type: ", typeid(typename T::key_compare).name()); } template void example_has_allocator_type(const T& container) { // Можно получить аллокатор из контейнера typename T::allocator_type alloc = container.get_allocator(); hack::log()("Allocator obtained successfully"); } template void example_is_string(const T& str) { hack::log()("String content: ", str, " (length: ", str.length(), ")"); } template void example_is_sequence_container(const T& container) { hack::log()("Sequence container with ", container.size(), " elements"); } template void example_is_container_adapter(T& adapter) { hack::log()("Container adapter with ", adapter.size(), " elements"); } template void example_is_associative_container(const T& container) { hack::log()("Associative container with ", container.size(), " elements"); } template void example_is_unordered_associative_container(const T& container) { hack::log()("Unordered associative container with ", container.size(), " elements"); } template void example_is_tuple_like(const T& tuple) { hack::log()("Tuple-like with ", std::tuple_size_v, " elements"); } template void example_is_fixed_array(const T& array) { hack::log()("Fixed array with ", std::extent_v, " elements"); } template void example_is_std_array(const T& array) { hack::log()("std::array with ", array.size(), " elements"); } template void example_is_any_container(const T& container) { hack::log()("Any container with ", container.size(), " elements"); } template void example_is_iterable(const T& iterable) { hack::log()("Iterable object"); } template void example_is_sized(const T& sized) { if constexpr (hack::concepts::has_size) hack::log()("Sized object: ", sized.size(), " elements"); else hack::log()("Sized object (compile-time size)"); } template void check_support(const T& value) { if constexpr (hack::concepts::not_supported) hack::log()("Type is NOT supported by this library"); else hack::log()("Type is supported"); } template void example_is_contiguous_container(const T& container) { hack::log()("Contiguous memory container"); } template requires hack::concepts::can_push_front void example_can_push_front(Container& container, Value&& value) { container.push_front(std::forward(value)); hack::log()("Pushed front value: ", value); } template requires hack::concepts::can_push_back void example_can_push_back(Container& container, Value&& value) { container.push_back(std::forward(value)); hack::log()("Pushed back value: ", value); } template requires hack::concepts::can_find void example_can_find(Container& container, Key&& key) { auto it = container.find(std::forward(key)); if (it != container.end()) hack::log()("Found value: ", *it); else hack::log()("Value not found: ", key); } auto main(int argc, char *argv[]) -> int { std::vector vec = { 1, 2, 3 }; std::map map = {{ 1, "one" }, { 2, "two" }}; std::set set = { 5, 3, 1, 4, 2 }; std::unordered_map umap = {{ 1, "uno" }, { 2, "dos" }}; std::list list = { 1.1, 2.2, 3.3 }; std::deque deque = { 'a', 'b', 'c' }; std::stack stack; stack.push(1); stack.push(2); std::string str = "Hello"; std::tuple tuple = {1, "test", 3.14}; int fixed_array[5] = {1, 2, 3, 4, 5}; std::array std_array = {1.0f, 2.0f, 3.0f}; int a = 10; struct custom_type { int x; }; custom_type custom; example_has_value_type(vec); // example_has_value_type(a); // выдаст ошибку т.к. у a нет встроенного value_type example_has_key_type(map); example_has_mapped_type(map); // example_has_mapped_type(set); // выдаст ошибку т.к. у set нет типа mapped_type. Этот тип характерен для контейнеров, которые хранят пары "ключ-значение". example_has_iterator(vec); example_has_size(vec); example_has_key_compare(map); example_has_allocator_type(map); example_is_string(str); example_is_sequence_container(vec); example_is_sequence_container(list); example_is_container_adapter(stack); example_is_unordered_associative_container(umap); example_is_tuple_like(tuple); example_is_fixed_array(fixed_array); example_is_std_array(std_array); example_is_any_container(vec); example_is_iterable(vec); example_is_sized(vec); check_support(a); check_support(custom); example_is_contiguous_container(vec); example_can_push_front(list, 0); example_can_push_back(vec, 99); example_can_find(set, 3); return 0; }