start logger impl

This commit is contained in:
2025-09-09 12:11:45 +03:00
parent 00d96e3e2c
commit 86d4535401
7 changed files with 331 additions and 230 deletions

View File

@@ -15,9 +15,9 @@
+ security - что-то типа защиты от чего-то
+ utils - вспомогательные решения для библиотеки
- logger - реализация логирования
- exception - универсальный класс обработки ошибок
- iterators - набор разнообразных реализаций итераторов
- logger - реализация логирования
+ - задукоментированно с коментариями и примерами
- - доки в раборте, нужно делать и разбирать

View File

@@ -1,7 +1,7 @@
#include "hack/concepts/concepts.hpp"
#include "hack/logger/logger.hpp"
template<hack::concepts::modern::has_value_type T>
template<hack::concepts::has_value_type T>
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<hack::concepts::modern::has_key_type T>
template<hack::concepts::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>
template<hack::concepts::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>
template<hack::concepts::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>
template<hack::concepts::has_size T>
void example_has_size(const T& container)
{
hack::log()("Container size:", container.size());
}
template<hack::concepts::modern::has_key_compare T>
template<hack::concepts::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>
template<hack::concepts::has_allocator_type T>
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<hack::concepts::modern::is_string T>
template<hack::concepts::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>
template<hack::concepts::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>
template<hack::concepts::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>
template<hack::concepts::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>
template<hack::concepts::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>
template<hack::concepts::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>
template<hack::concepts::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>
template<hack::concepts::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>
template<hack::concepts::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>
template<hack::concepts::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>
template<hack::concepts::is_iterable T>
void example_is_iterable(const T& iterable)
{
hack::log()("Iterable object");
}
template<hack::concepts::modern::is_sized T>
template<hack::concepts::is_sized T>
void example_is_sized(const T& sized)
{
if constexpr (hack::concepts::modern::has_size<T>)
if constexpr (hack::concepts::has_size<T>)
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<typename T>
void check_support(const T& value)
{
if constexpr (hack::concepts::modern::not_supported<T>)
if constexpr (hack::concepts::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>
template<hack::concepts::has_key_value_semantics T>
void example_has_key_value_semantics(T& container)
{
if constexpr (hack::concepts::modern::has_mapped_type<T>)
if constexpr (hack::concepts::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>
template<hack::concepts::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>
requires hack::concepts::can_push_front<Container, Value>
void example_can_push_front(Container& container, Value&& value)
{
container.push_front(std::forward<Value>(value));
@@ -163,7 +163,7 @@ void example_can_push_front(Container& container, Value&& value)
}
template<typename Container, typename Value>
requires hack::concepts::modern::can_push_back<Container, Value>
requires hack::concepts::can_push_back<Container, Value>
void example_can_push_back(Container& container, Value&& value)
{
container.push_back(std::forward<Value>(value));
@@ -171,7 +171,7 @@ void example_can_push_back(Container& container, Value&& value)
}
template<typename Container, typename Key>
requires hack::concepts::modern::can_find<Container, Key>
requires hack::concepts::can_find<Container, Key>
void example_can_find(Container& container, Key&& key)
{
auto it = container.find(std::forward<Key>(key));

View File

@@ -0,0 +1,24 @@
#include <vector>
#include <map>
#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<std::string> vs = { "a", "b", "c" };
std::map<int, int> 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;
}

View File

@@ -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

View File

@@ -18,42 +18,7 @@
#include <utility>
#include <concepts>
// HERE
// Это старая версия. Перед удалением нужнопроверить ее работу по сравнению с работой новой версии
namespace hack::concepts
{
template<typename T>
concept is_map = std::same_as<T, std::map<typename T::key_type, typename T::mapped_type, typename T::key_compare, typename T::allocator_type>> ||
std::same_as<T, std::unordered_map<typename T::key_type, typename T::mapped_type, typename T::hasher, typename T::key_equal, typename T::allocator_type>>;
template<typename T>
concept is_tuple = requires (T t) { std::tuple_cat(t, std::make_tuple(1, "tuple")); };
template<typename T>
concept is_set = std::same_as<T, std::set<typename T::key_type, typename T::key_compare, typename T::allocator_type>>;
template<typename T>
concept is_unordered_set = std::same_as<T, std::unordered_set<typename T::key_type>>;
template<typename T>
concept is_forward_list = std::same_as<T, std::forward_list<typename T::value_type>>;
template<typename T>
concept is_string = std::is_convertible_v<T, std::string_view>;
template<typename T, std::size_t N = 0>
concept is_sequence_container = std::same_as<T, std::vector<typename T::value_type>> || std::same_as<T, std::list<typename T::value_type>> || (std::is_array_v<T> && N > 0);
template<typename T>
concept is_associative_container = is_map<T> || is_tuple<T> || is_set<T> || is_unordered_set<T>;
template<typename T>
concept not_defined = !std::enable_if_t<!(std::integral<T> || is_sequence_container<T> || is_map<T> || is_tuple<T> || is_set<T> || is_unordered_set<T> ||
is_forward_list<T> || std::is_array<T>() || is_string<T>), bool>() == true;
}
namespace hack::concepts::modern
{
// Базовые концепты для обнаружения характеристик типов.
// Эти концепты являются строительными блоками для более сложных проверок.
@@ -302,4 +267,16 @@ namespace hack::concepts::modern
// Ключевой концепт для алгоритмов поиска и проверки существования элементов
template<typename Container, typename Key>
concept can_find = requires(Container c, Key&& key) { c.find(std::forward<Key>(key)); };
// @brief Проверяет, является ли данное числом
// @details Проверяет на основные операции
template<typename T>
concept is_number = requires(T value) {
requires std::is_arithmetic_v<T>; // Включает все арифметические типы
value + value; // Проверяет арифметические операции
value - value;
value * value;
value / value;
};
}

214
src/hack/logger/logger.OLD.hpp Executable file
View File

@@ -0,0 +1,214 @@
#pragma once
#include <experimental/source_location>
#include <string>
#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<typename... Args>
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<typename T, typename U>
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<typename T, typename... Args>
static void print(const T& data, const Args&... args)
{
--count;
print_t(data);
print(args...);
}
template<concepts::is_string T>
static void print_t(const T& data)
{
std::cout << data << (count != 0 ? devider : "");
}
template<std::integral T>
static void print_t(const T& data)
{
std::cout << data << (count != 0 ? devider : "");
}
template<concepts::is_sequence_container T>
static void print_t(const T& data)
{
std::cout << "{ ";
std::copy(data.cbegin(), data.cend(), iterators::sequence_ostream_iterator<typename T::value_type>(data.size(), std::cout));
std::cout << " }" << (count != 0 ? devider : "");
}
// HERE
// реализовать это с учетом новых концептов
template<concepts::is_set T>
static void print_t(const T& data)
{
std::cout << "{ ";
std::copy(data.cbegin(), data.cend(), iterators::sequence_ostream_iterator<typename T::value_type>(data.size(), std::cout));
std::cout << " }" << (count != 0 ? devider : "");
}
template<concepts::is_unordered_set T>
static void print_t(const T& data)
{
std::cout << "{ ";
std::copy(data.cbegin(), data.cend(), iterators::sequence_ostream_iterator<typename T::value_type>(data.size(), std::cout));
std::cout << " }" << (count != 0 ? devider : "");
}
template<concepts::is_forward_list T>
static void print_t(const T& data)
{
std::cout << "{ ";
std::copy(data.cbegin(), data.cend(), iterators::sequence_ostream_iterator<typename T::value_type>(std::distance(data.cbegin(), data.cend()), std::cout));
std::cout << " }" << (count != 0 ? devider : "");
}
template<concepts::is_map T>
static void print_t(const T& data)
{
std::cout << "{";
std::copy(data.begin(), data.cend(), iterators::associative_ostream_iterator<typename T::value_type>(data.size(), std::cout));
std::cout << "}" << (count != 0 ? devider : "");
}
template<concepts::is_tuple T, typename std::size_t... idx>
static void print_t(const T& data)
{
print_t(data, std::make_index_sequence<std::tuple_size<T>::value>{});
}
template<concepts::not_defined T>
static void print_t(const T& data)
{
std::cout << data << (count != 0 ? devider : "");
}
template<typename T, typename std::size_t... idx>
static void print_t(const T& data, std::index_sequence<idx...>)
{
std::cout << "{ ";
((std::cout << std::get<idx>(data) << (idx != std::tuple_size<T>::value - 1 ? devider : "")), ...);
std::cout << " }" << (count != 0 ? devider : "");
}
template<typename T>
static void print_t(const hack::patterns::ring_buffer<T>& 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<typename... Args>
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<typename... Args>
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;
}
};
}

View File

@@ -1,14 +1,15 @@
#pragma once
#include <experimental/source_location>
#include <source_location> // C++20
#include <string>
#include <sstream>
#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 <execinfo.h>
#include <iostream>
#include <cxxabi.h>
// 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<logger>
{
public:
log(std::string devider_ = " ", std::experimental::source_location location_ = std::experimental::source_location::current()) : location { location_ }
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()
{
this->devider = devider_;
m_no_func = m_base_config.m_no_func;
m_devider = m_base_config.m_devider;
}
log(log&) = delete;
log(log&&) = delete;
public:
template<typename... Args>
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<typename T, typename U>
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<typename T, typename... Args>
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<concepts::is_string T>
static void print_t(const T& data)
{
std::cout << data << (count != 0 ? devider : "");
}
void print_impl() { std::cout << std::endl; }
template<std::integral T>
static void print_t(const T& data)
template<typename T>
requires concepts::is_string<T>
void pring_first(const T& data)
{
std::cout << data << (count != 0 ? devider : "");
}
template<concepts::is_sequence_container T>
static void print_t(const T& data)
{
std::cout << "{ ";
std::copy(data.cbegin(), data.cend(), iterators::sequence_ostream_iterator<typename T::value_type>(data.size(), std::cout));
std::cout << " }" << (count != 0 ? devider : "");
}
template<concepts::is_set T>
static void print_t(const T& data)
{
std::cout << "{ ";
std::copy(data.cbegin(), data.cend(), iterators::sequence_ostream_iterator<typename T::value_type>(data.size(), std::cout));
std::cout << " }" << (count != 0 ? devider : "");
}
template<concepts::is_unordered_set T>
static void print_t(const T& data)
{
std::cout << "{ ";
std::copy(data.cbegin(), data.cend(), iterators::sequence_ostream_iterator<typename T::value_type>(data.size(), std::cout));
std::cout << " }" << (count != 0 ? devider : "");
}
template<concepts::is_forward_list T>
static void print_t(const T& data)
{
std::cout << "{ ";
std::copy(data.cbegin(), data.cend(), iterators::sequence_ostream_iterator<typename T::value_type>(std::distance(data.cbegin(), data.cend()), std::cout));
std::cout << " }" << (count != 0 ? devider : "");
}
template<concepts::is_map T>
static void print_t(const T& data)
{
std::cout << "{";
std::copy(data.begin(), data.cend(), iterators::associative_ostream_iterator<typename T::value_type>(data.size(), std::cout));
std::cout << "}" << (count != 0 ? devider : "");
}
template<concepts::is_tuple T, typename std::size_t... idx>
static void print_t(const T& data)
{
print_t(data, std::make_index_sequence<std::tuple_size<T>::value>{});
}
template<typename T, typename std::size_t... idx>
static void print_t(const T& data, std::index_sequence<idx...>)
{
std::cout << "{ ";
((std::cout << std::get<idx>(data) << (idx != std::tuple_size<T>::value - 1 ? devider : "")), ...);
std::cout << " }" << (count != 0 ? devider : "");
}
template<concepts::not_defined T>
static void print_t(const T& data)
{
std::cout << data << (count != 0 ? devider : "");
std::cout << data << (m_count != 0 ? m_devider : "");
}
template<typename T>
static void print_t(const hack::patterns::ring_buffer<T>& rb)
requires concepts::is_number<T>
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_;
logger::instance().set_location(location);
return logger::instance();
}
warn(warn&) = delete;
warn(warn&&) = delete;
public:
template<typename... Args>
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<typename... Args>
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;
}
};
}