Files
hack/bin/examples/concepts/main.cpp
2025-09-05 18:29:24 +03:00

233 lines
7.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "hack/concepts/concepts.hpp"
#include "hack/logger/logger.hpp"
template<hack::concepts::modern::has_value_type T>
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<hack::concepts::modern::has_key_type T>
void example_has_key_type(const T& container)
{
hack::log()("Key type: ", typeid(typename T::key_type).name());
}
template<hack::concepts::modern::has_mapped_type T>
void example_has_mapped_type(const T& container)
{
hack::log()("Mapped type: ", typeid(typename T::mapped_type).name());
}
template<hack::concepts::modern::has_iterator T>
void example_has_iterator(const T& container)
{
hack::log()("Container is iterable, size: ", std::distance(container.begin(), container.end()));
}
template<hack::concepts::modern::has_size T>
void example_has_size(const T& container)
{
hack::log()("Container size:", container.size());
}
template<hack::concepts::modern::has_key_compare T>
void example_has_key_compare(const T& container)
{
hack::log()("Key compare type: ", typeid(typename T::key_compare).name());
}
template<hack::concepts::modern::has_allocator_type T>
void example_has_allocator_type(const T& container)
{
// Можно получить аллокатор из контейнера
typename T::allocator_type alloc = container.get_allocator();
hack::log()("Allocator obtained successfully");
}
template<hack::concepts::modern::is_string T>
void example_is_string(const T& str)
{
hack::log()("String content: ", str, " (length: ", str.length(), ")");
}
template<hack::concepts::modern::is_sequence_container T>
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())
hack::log()("First element: ", container[0]);
}
template<hack::concepts::modern::is_container_adapter T>
void example_is_container_adapter(T& adapter)
{
hack::log()("Container adapter with ", adapter.size(), " elements");
}
template<hack::concepts::modern::is_associative_container T>
void example_is_associative_container(const T& container)
{
hack::log()("Associative container with ", container.size(), " elements");
}
template<hack::concepts::modern::is_unordered_associative_container T>
void example_is_unordered_associative_container(const T& container)
{
hack::log()("Unordered associative container with ", container.size(), " elements");
}
template<hack::concepts::modern::is_tuple_like T>
void example_is_tuple_like(const T& tuple)
{
hack::log()("Tuple-like with ", std::tuple_size_v<T>, " elements");
}
template<hack::concepts::modern::is_fixed_array T>
void example_is_fixed_array(const T& array)
{
hack::log()("Fixed array with ", std::extent_v<T>, " elements");
}
template<hack::concepts::modern::is_std_array T>
void example_is_std_array(const T& array)
{
hack::log()("std::array with ", array.size(), " elements");
}
template<hack::concepts::modern::is_any_container T>
void example_is_any_container(const T& container)
{
hack::log()("Any container with ", container.size(), " elements");
}
template<hack::concepts::modern::is_iterable T>
void example_is_iterable(const T& iterable)
{
hack::log()("Iterable object");
}
template<hack::concepts::modern::is_sized T>
void example_is_sized(const T& sized)
{
if constexpr (hack::concepts::modern::has_size<T>)
hack::log()("Sized object: ", sized.size(), " elements");
else
hack::log()("Sized object (compile-time size)");
}
template<typename T>
void check_support(const T& value)
{
if constexpr (hack::concepts::modern::not_supported<T>)
hack::log()("Type is NOT supported by this library");
else
hack::log()("Type is supported");
}
template<hack::concepts::modern::has_key_value_semantics T>
void example_has_key_value_semantics(T& container)
{
if constexpr (hack::concepts::modern::has_mapped_type<T>)
hack::log()("Key-value container, sample access demonstrated");
else
hack::log()("Set-like container");
}
template<hack::concepts::modern::is_contiguous_container T>
void example_is_contiguous_container(const T& container)
{
hack::log()("Contiguous memory container");
}
template<typename Container, typename Value>
requires hack::concepts::modern::can_push_front<Container, Value>
void example_can_push_front(Container& container, Value&& value)
{
container.push_front(std::forward<Value>(value));
hack::log()("Pushed front value: ", value);
}
template<typename Container, typename Value>
requires hack::concepts::modern::can_push_back<Container, Value>
void example_can_push_back(Container& container, Value&& value)
{
container.push_back(std::forward<Value>(value));
hack::log()("Pushed back value: ", value);
}
template<typename Container, typename Key>
requires hack::concepts::modern::can_find<Container, Key>
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
{
std::vector<int> vec = { 1, 2, 3 };
std::map<int, std::string> map = {{ 1, "one" }, { 2, "two" }};
std::set<int> set = { 5, 3, 1, 4, 2 };
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;
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_random_access_container(vec);
example_is_container_adapter(stack);
example_is_associative_container(set);
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_has_key_value_semantics(map);
example_is_contiguous_container(vec);
example_can_push_front(list, 0);
example_can_push_back(vec, 99);
example_can_find(set, 3);
return 0;
}