diff --git a/README.md b/README.md index a311918..5bf9958 100755 --- a/README.md +++ b/README.md @@ -15,9 +15,9 @@ + security - что-то типа защиты от чего-то + utils - вспомогательные решения для библиотеки +- logger - реализация логирования - exception - универсальный класс обработки ошибок - iterators - набор разнообразных реализаций итераторов -- logger - реализация логирования + - задукоментированно с коментариями и примерами - - доки в раборте, нужно делать и разбирать diff --git a/bin/examples/concepts/main.cpp b/bin/examples/concepts/main.cpp index 53a5f16..0d8d2b3 100644 --- a/bin/examples/concepts/main.cpp +++ b/bin/examples/concepts/main.cpp @@ -1,7 +1,7 @@ #include "hack/concepts/concepts.hpp" #include "hack/logger/logger.hpp" -template +template void example_has_value_type(const T& container) { /* @@ -16,37 +16,37 @@ void example_has_value_type(const T& container) hack::log()("Value type: ", typeid(typename T::value_type).name()); } -template +template void example_has_key_type(const T& container) { hack::log()("Key type: ", typeid(typename T::key_type).name()); } -template +template void example_has_mapped_type(const T& container) { hack::log()("Mapped type: ", typeid(typename T::mapped_type).name()); } -template +template void example_has_iterator(const T& container) { hack::log()("Container is iterable, size: ", std::distance(container.begin(), container.end())); } -template +template void example_has_size(const T& container) { hack::log()("Container size:", container.size()); } -template +template void example_has_key_compare(const T& container) { hack::log()("Key compare type: ", typeid(typename T::key_compare).name()); } -template +template void example_has_allocator_type(const T& container) { // Можно получить аллокатор из контейнера @@ -54,77 +54,77 @@ void example_has_allocator_type(const T& container) hack::log()("Allocator obtained successfully"); } -template +template void example_is_string(const T& str) { hack::log()("String content: ", str, " (length: ", str.length(), ")"); } -template +template void example_is_sequence_container(const T& container) { hack::log()("Sequence container with ", container.size(), " elements"); } -template +template void example_is_random_access_container(T& container) { if (!container.empty()) hack::log()("First element: ", container[0]); } -template +template void example_is_container_adapter(T& adapter) { hack::log()("Container adapter with ", adapter.size(), " elements"); } -template +template void example_is_associative_container(const T& container) { hack::log()("Associative container with ", container.size(), " elements"); } -template +template void example_is_unordered_associative_container(const T& container) { hack::log()("Unordered associative container with ", container.size(), " elements"); } -template +template void example_is_tuple_like(const T& tuple) { hack::log()("Tuple-like with ", std::tuple_size_v, " elements"); } -template +template void example_is_fixed_array(const T& array) { hack::log()("Fixed array with ", std::extent_v, " elements"); } -template +template void example_is_std_array(const T& array) { hack::log()("std::array with ", array.size(), " elements"); } -template +template void example_is_any_container(const T& container) { hack::log()("Any container with ", container.size(), " elements"); } -template +template void example_is_iterable(const T& iterable) { hack::log()("Iterable object"); } -template +template void example_is_sized(const T& sized) { - if constexpr (hack::concepts::modern::has_size) + if constexpr (hack::concepts::has_size) hack::log()("Sized object: ", sized.size(), " elements"); else hack::log()("Sized object (compile-time size)"); @@ -133,29 +133,29 @@ void example_is_sized(const T& sized) template void check_support(const T& value) { - if constexpr (hack::concepts::modern::not_supported) + if constexpr (hack::concepts::not_supported) hack::log()("Type is NOT supported by this library"); else hack::log()("Type is supported"); } -template +template void example_has_key_value_semantics(T& container) { - if constexpr (hack::concepts::modern::has_mapped_type) + if constexpr (hack::concepts::has_mapped_type) hack::log()("Key-value container, sample access demonstrated"); else hack::log()("Set-like container"); } -template +template void example_is_contiguous_container(const T& container) { hack::log()("Contiguous memory container"); } template -requires hack::concepts::modern::can_push_front +requires hack::concepts::can_push_front void example_can_push_front(Container& container, Value&& value) { container.push_front(std::forward(value)); @@ -163,7 +163,7 @@ void example_can_push_front(Container& container, Value&& value) } template -requires hack::concepts::modern::can_push_back +requires hack::concepts::can_push_back void example_can_push_back(Container& container, Value&& value) { container.push_back(std::forward(value)); @@ -171,7 +171,7 @@ void example_can_push_back(Container& container, Value&& value) } template -requires hack::concepts::modern::can_find +requires hack::concepts::can_find void example_can_find(Container& container, Key&& key) { auto it = container.find(std::forward(key)); diff --git a/bin/examples/logger/main.cpp b/bin/examples/logger/main.cpp new file mode 100644 index 0000000..fec8100 --- /dev/null +++ b/bin/examples/logger/main.cpp @@ -0,0 +1,24 @@ +#include +#include +#include "hack/logger/logger.hpp" + +auto main(int argc, char *argv[]) -> int +{ + std::string str = "hi"; + int i = 1; + double d = 2.0; + float f = 3.f; + std::vector vs = { "a", "b", "c" }; + std::map mi = { { 1, 1 }, { 2, 2 }, { 3, 3 } }; + + hack::log().set_devider(", "); + hack::log().no_func(); + hack::log()(1, 2, 3.1f, 4.3, "asdf", "qwer", "xzcv"); + hack::log().set_devider(" = "); + hack::log()(1, 2, 3.1f, 4.3, "asdf", "qwer", "xzcv"); + hack::log().reset(); + hack::log()(1, 2, 3.1f, 4.3, "asdf", "qwer", "xzcv"); + + return 0; +} + diff --git a/bin/meson.build b/bin/meson.build index 83df1e9..cf101b7 100755 --- a/bin/meson.build +++ b/bin/meson.build @@ -4,7 +4,8 @@ executable( # 'examples/concepts/main.cpp', # 'examples/math/main.cpp', # 'examples/range/main.cpp', - 'examples/patterns/main.cpp', + # 'examples/patterns/main.cpp', + 'examples/logger/main.cpp', dependencies : deps, cpp_args: args, include_directories : inc diff --git a/src/hack/concepts/concepts.hpp b/src/hack/concepts/concepts.hpp index 09701ab..f68d484 100755 --- a/src/hack/concepts/concepts.hpp +++ b/src/hack/concepts/concepts.hpp @@ -18,42 +18,7 @@ #include #include -// HERE -// Это старая версия. Перед удалением нужнопроверить ее работу по сравнению с работой новой версии namespace hack::concepts -{ - template - concept is_map = std::same_as> || - std::same_as>; - - template - concept is_tuple = requires (T t) { std::tuple_cat(t, std::make_tuple(1, "tuple")); }; - - template - concept is_set = std::same_as>; - - template - concept is_unordered_set = std::same_as>; - - template - concept is_forward_list = std::same_as>; - - template - concept is_string = std::is_convertible_v; - - template - concept is_sequence_container = std::same_as> || std::same_as> || (std::is_array_v && N > 0); - - template - concept is_associative_container = is_map || is_tuple || is_set || is_unordered_set; - - - template - concept not_defined = !std::enable_if_t || is_sequence_container || is_map || is_tuple || is_set || is_unordered_set || - is_forward_list || std::is_array() || is_string), bool>() == true; -} - -namespace hack::concepts::modern { // Базовые концепты для обнаружения характеристик типов. // Эти концепты являются строительными блоками для более сложных проверок. @@ -302,4 +267,16 @@ namespace hack::concepts::modern // Ключевой концепт для алгоритмов поиска и проверки существования элементов template concept can_find = requires(Container c, Key&& key) { c.find(std::forward(key)); }; + + + // @brief Проверяет, является ли данное числом + // @details Проверяет на основные операции + template + concept is_number = requires(T value) { + requires std::is_arithmetic_v; // Включает все арифметические типы + value + value; // Проверяет арифметические операции + value - value; + value * value; + value / value; + }; } diff --git a/src/hack/logger/logger.OLD.hpp b/src/hack/logger/logger.OLD.hpp new file mode 100755 index 0000000..5e95695 --- /dev/null +++ b/src/hack/logger/logger.OLD.hpp @@ -0,0 +1,214 @@ +#pragma once + +#include +#include + +#include "hack/utils/color.hpp" +#include "hack/concepts/concepts.hpp" +#include "hack/iterators/sequence_ostream_iterator.hpp" +#include "hack/iterators/associative_ostream_iterator.hpp" + +#include "hack/patterns/ring_buffer.hpp" + +// HERE +// и нужно сделать реализацию где выводлится все в одной линии но при помощи цикла +// типа такого: +// for (auto i : range) hack::log(hack::log::line)(i); +namespace hack +{ + class log + { + public: + log(std::string devider_ = " ", std::experimental::source_location location_ = std::experimental::source_location::current()) : location { location_ } + { + this->devider = devider_; + } + + log(log&) = delete; + log(log&&) = delete; + + public: + template + void operator() (const Args&... args) + { + count = sizeof...(Args); + prepare(make_type_view, location); + print(args...); + } + + private: + std::experimental::source_location location; + inline static int count = 0; + inline static std::string devider = " "; + + private: + template + void prepare(T t, U u) + { + std::cout << t + << u.file_name() << ":" << utils::color::reset + << utils::color::italic << utils::color::yellow << u.function_name() << "()" << utils::color::reset + << utils::color::bold << utils::color::blue << "[" << u.line() << "]" << utils::color::reset << ": "; + } + + static void print() { std::cout << std::endl; } + + static std::ostream& make_type_view(std::ostream &os) + { + os << utils::color::bold << utils::color::green << "[ok]" << utils::color::reset << utils::color::green; + return os; + } + + template + static void print(const T& data, const Args&... args) + { + --count; + print_t(data); + print(args...); + } + + template + static void print_t(const T& data) + { + std::cout << data << (count != 0 ? devider : ""); + } + + template + static void print_t(const T& data) + { + std::cout << data << (count != 0 ? devider : ""); + } + + template + static void print_t(const T& data) + { + std::cout << "{ "; + std::copy(data.cbegin(), data.cend(), iterators::sequence_ostream_iterator(data.size(), std::cout)); + std::cout << " }" << (count != 0 ? devider : ""); + } + + // HERE + // реализовать это с учетом новых концептов + template + static void print_t(const T& data) + { + std::cout << "{ "; + std::copy(data.cbegin(), data.cend(), iterators::sequence_ostream_iterator(data.size(), std::cout)); + std::cout << " }" << (count != 0 ? devider : ""); + } + + template + static void print_t(const T& data) + { + std::cout << "{ "; + std::copy(data.cbegin(), data.cend(), iterators::sequence_ostream_iterator(data.size(), std::cout)); + std::cout << " }" << (count != 0 ? devider : ""); + } + + template + static void print_t(const T& data) + { + std::cout << "{ "; + std::copy(data.cbegin(), data.cend(), iterators::sequence_ostream_iterator(std::distance(data.cbegin(), data.cend()), std::cout)); + std::cout << " }" << (count != 0 ? devider : ""); + } + + template + static void print_t(const T& data) + { + std::cout << "{"; + std::copy(data.begin(), data.cend(), iterators::associative_ostream_iterator(data.size(), std::cout)); + std::cout << "}" << (count != 0 ? devider : ""); + } + + template + static void print_t(const T& data) + { + print_t(data, std::make_index_sequence::value>{}); + } + + template + static void print_t(const T& data) + { + std::cout << data << (count != 0 ? devider : ""); + } + + template + static void print_t(const T& data, std::index_sequence) + { + std::cout << "{ "; + ((std::cout << std::get(data) << (idx != std::tuple_size::value - 1 ? devider : "")), ...); + std::cout << " }" << (count != 0 ? devider : ""); + } + + template + static void print_t(const hack::patterns::ring_buffer& rb) + { + print_t(rb.get_src()); + } + + friend class warn; + friend class error; + }; + + class warn : public log + { + public: + warn(std::string devider_ = " ", std::experimental::source_location location_ = std::experimental::source_location::current()) : location { location_ } + { + this->devider = devider_; + } + + warn(warn&) = delete; + warn(warn&&) = delete; + + public: + template + void operator() (const Args&... args) + { + prepare(make_type_view, location); + count = sizeof...(Args); + print(args...); + } + + private: + std::experimental::source_location location; + + private: + static std::ostream& make_type_view(std::ostream &os) + { + os << utils::color::bold << utils::color::yellow << "[WARN]" << utils::color::reset << utils::color::yellow; + return os; + } + }; + + class error : public log + { + public: + error(std::string devider_ = " ", std::experimental::source_location location_ = std::experimental::source_location::current()) : location { location_ } + { + this->devider = devider_; + } + error(error&) = delete; + error(error&&) = delete; + + public: + template + void operator() (const Args&... args) + { + prepare(make_type_view, location); + count = sizeof...(Args); + print(args...); + } + + private: + std::experimental::source_location location; + + private: + static std::ostream& make_type_view(std::ostream &os) + { + os << utils::color::bold << utils::color::red << "[ERROR]" << utils::color::reset << utils::color::red; + return os; + } + }; +} diff --git a/src/hack/logger/logger.hpp b/src/hack/logger/logger.hpp index 2792d32..c4b30a0 100755 --- a/src/hack/logger/logger.hpp +++ b/src/hack/logger/logger.hpp @@ -1,14 +1,15 @@ #pragma once -#include +#include // C++20 #include - +#include #include "hack/utils/color.hpp" +#include "hack/patterns/singleton.hpp" #include "hack/concepts/concepts.hpp" -#include "hack/iterators/sequence_ostream_iterator.hpp" -#include "hack/iterators/associative_ostream_iterator.hpp" -#include "hack/patterns/ring_buffer.hpp" +#include +#include +#include // HERE // и нужно сделать реализацию где выводлится все в одной линии но при помощи цикла @@ -16,197 +17,81 @@ // for (auto i : range) hack::log(hack::log::line)(i); namespace hack { - class log + class logger : public hack::patterns::singleton { public: - log(std::string devider_ = " ", std::experimental::source_location location_ = std::experimental::source_location::current()) : location { location_ } - { - this->devider = devider_; + void set_location(std::source_location location) { m_location = location; } + void set_devider(std::string devider) { m_devider = devider; } + void no_func() { m_no_func = true; }; + void reset() + { + m_no_func = m_base_config.m_no_func; + m_devider = m_base_config.m_devider; } - log(log&) = delete; - log(log&&) = delete; - - public: template void operator() (const Args&... args) { - count = sizeof...(Args); - prepare(make_type_view, location); - print(args...); + m_count = sizeof...(Args); + prepare(); + print_impl(args...); } private: - std::experimental::source_location location; - inline static int count = 0; - inline static std::string devider = " "; + struct config + { + bool m_no_func = false; + std::string m_devider = " "; + } m_base_config; private: - template - void prepare(T t, U u) + void prepare() { - std::cout << t - << u.file_name() << ":" << utils::color::reset - << utils::color::italic << utils::color::yellow << u.function_name() << "()" << utils::color::reset - << utils::color::bold << utils::color::blue << "[" << u.line() << "]" << utils::color::reset << ": "; - } + std::stringstream ss; + ss << utils::color::bold << utils::color::green << "[ok]" << utils::color::reset << utils::color::green + << m_location.file_name() << ":" << utils::color::reset; - static void print() { std::cout << std::endl; } + if (!m_no_func) + ss << utils::color::italic << utils::color::yellow << m_location.function_name() << utils::color::reset; - static std::ostream& make_type_view(std::ostream &os) - { - os << utils::color::bold << utils::color::green << "[ok]" << utils::color::reset << utils::color::green; - return os; + ss << utils::color::bold << utils::color::blue << "[" << m_location.line() << "]" << utils::color::reset << ": "; + std::cout << ss.str(); } template - static void print(const T& data, const Args&... args) + void print_impl(const T& data, const Args&... args) { - --count; - print_t(data); - print(args...); + --m_count; + pring_first(data); + print_impl(args...); } - template - static void print_t(const T& data) - { - std::cout << data << (count != 0 ? devider : ""); - } + void print_impl() { std::cout << std::endl; } - template - static void print_t(const T& data) + template + requires concepts::is_string + void pring_first(const T& data) { - std::cout << data << (count != 0 ? devider : ""); - } - - template - static void print_t(const T& data) - { - std::cout << "{ "; - std::copy(data.cbegin(), data.cend(), iterators::sequence_ostream_iterator(data.size(), std::cout)); - std::cout << " }" << (count != 0 ? devider : ""); - } - - template - static void print_t(const T& data) - { - std::cout << "{ "; - std::copy(data.cbegin(), data.cend(), iterators::sequence_ostream_iterator(data.size(), std::cout)); - std::cout << " }" << (count != 0 ? devider : ""); - } - - template - static void print_t(const T& data) - { - std::cout << "{ "; - std::copy(data.cbegin(), data.cend(), iterators::sequence_ostream_iterator(data.size(), std::cout)); - std::cout << " }" << (count != 0 ? devider : ""); - } - - template - static void print_t(const T& data) - { - std::cout << "{ "; - std::copy(data.cbegin(), data.cend(), iterators::sequence_ostream_iterator(std::distance(data.cbegin(), data.cend()), std::cout)); - std::cout << " }" << (count != 0 ? devider : ""); - } - - template - static void print_t(const T& data) - { - std::cout << "{"; - std::copy(data.begin(), data.cend(), iterators::associative_ostream_iterator(data.size(), std::cout)); - std::cout << "}" << (count != 0 ? devider : ""); - } - - template - static void print_t(const T& data) - { - print_t(data, std::make_index_sequence::value>{}); - } - - template - static void print_t(const T& data, std::index_sequence) - { - std::cout << "{ "; - ((std::cout << std::get(data) << (idx != std::tuple_size::value - 1 ? devider : "")), ...); - std::cout << " }" << (count != 0 ? devider : ""); - } - - template - static void print_t(const T& data) - { - std::cout << data << (count != 0 ? devider : ""); + std::cout << data << (m_count != 0 ? m_devider : ""); } template - static void print_t(const hack::patterns::ring_buffer& rb) + requires concepts::is_number + void pring_first(const T& data) { - print_t(rb.get_src()); + std::cout << data << (m_count != 0 ? m_devider : ""); } - friend class warn; - friend class error; + private: + std::source_location m_location; + std::size_t m_count = 0; + std::string m_devider = m_base_config.m_devider; + bool m_no_func = m_base_config.m_no_func; }; - class warn : public log + inline logger& log(std::source_location location = std::source_location::current()) { - public: - warn(std::string devider_ = " ", std::experimental::source_location location_ = std::experimental::source_location::current()) : location { location_ } - { - this->devider = devider_; - } - - warn(warn&) = delete; - warn(warn&&) = delete; - - public: - template - void operator() (const Args&... args) - { - prepare(make_type_view, location); - count = sizeof...(Args); - print(args...); - } - - private: - std::experimental::source_location location; - - private: - static std::ostream& make_type_view(std::ostream &os) - { - os << utils::color::bold << utils::color::yellow << "[WARN]" << utils::color::reset << utils::color::yellow; - return os; - } - }; - - class error : public log - { - public: - error(std::string devider_ = " ", std::experimental::source_location location_ = std::experimental::source_location::current()) : location { location_ } - { - this->devider = devider_; - } - error(error&) = delete; - error(error&&) = delete; - - public: - template - void operator() (const Args&... args) - { - prepare(make_type_view, location); - count = sizeof...(Args); - print(args...); - } - - private: - std::experimental::source_location location; - - private: - static std::ostream& make_type_view(std::ostream &os) - { - os << utils::color::bold << utils::color::red << "[ERROR]" << utils::color::reset << utils::color::red; - return os; - } - }; + logger::instance().set_location(location); + return logger::instance(); + } }