diff --git a/bin/main.cpp b/bin/main.cpp index 7f5b6c2..2736396 100644 --- a/bin/main.cpp +++ b/bin/main.cpp @@ -1,30 +1,55 @@ #include +#include +#include + #include "string/string.hpp" #include "range/range.hpp" #include "container/container.hpp" +#include "logger/logger.hpp" int main(int argc, char *argv[]) { - {// ex: split_str - std::string str { "asdf,qwer,zxcv" }; - hack::string::v_str v = hack::string::split_str(str, ','); - for (const auto& c : v) std::cout << c << std::endl; - } + // {// ex: split_str + // std::string str { "asdf,qwer,zxcv" }; + // hack::string::v_str v = hack::string::split_str(str, ','); + // for (const auto& c : v) std::cout << c << std::endl; + // } + // + // {// ex: within + // std::cout << std::boolalpha << hack::range::within(12, 34, 12, 23, 31, 17, 22, 33) << std::endl; + // } + // + // {// ex: v_multiset + // std::vector v; + // hack::container::v_multiset(v, "asdf", "qwer", "zcv"); + // for(const auto& c : v) std::cout << c << std::endl; + // } + // + // {// ex: s_multiset + // std::set s; + // hack::container::s_multiset(s, 1, 2, 3, 3, 2, 1); + // for(const auto& c : s) std::cout << c << std::endl; + // } - {// ex: within - std::cout << std::boolalpha << hack::range::within(12, 34, 12, 23, 31, 17, 22, 33) << std::endl; - } - - {// ex: v_multiset - std::vector v; - hack::container::v_multiset(v, "asdf", "qwer", "zcv"); - for(const auto& c : v) std::cout << c << std::endl; - } + {// ex: log + hack::log()(1234, "run in main", 1234); + hack::warn(" # ")(1234, "run in main", 1234); + hack::error(" - ")(1234, "run in main", 1234); - {// ex: s_multiset - std::set s; - hack::container::s_multiset(s, 1, 2, 3, 3, 2, 1); - for(const auto& c : s) std::cout << c << std::endl; + std::string str { "hi" }; + hack::log()(str); + + std::vector vs { "asdf", "qwer", "zxcv" }; + hack::log()("vector", vs, 1, 2, 'a'); + + std::list ls { "asdf", "qwer", "zxcv" }; + hack::log()(vs, ls); + + std::map m { { 1, "asdf" }, { 2, "qwer" }, { 3, "zxcv" } }; + hack::log()(vs, ls, m); + + std::tuple tp { 1, "tuple test", false }; + hack::log()(tp); } } diff --git a/bin/meson.build b/bin/meson.build index 727a5f2..312c7e2 100644 --- a/bin/meson.build +++ b/bin/meson.build @@ -1,6 +1,9 @@ +deps += view_dep +deps += iterators_dep deps += string_dep deps += range_dep -deps += range_dep +deps += container_dep +deps += logger_dep executable( 'hack', 'main.cpp', diff --git a/meson.build b/meson.build index 788e89d..d1d1702 100644 --- a/meson.build +++ b/meson.build @@ -3,7 +3,7 @@ project( 'hack', 'cpp', version : '0.0.1', - default_options : ['cpp_std=c++20'] + default_options : ['cpp_std=c++2a'] ) add_project_arguments ( diff --git a/src/container/container.hpp b/src/container/container.hpp index 92282de..fbb47b6 100644 --- a/src/container/container.hpp +++ b/src/container/container.hpp @@ -6,7 +6,7 @@ namespace hack::container { template - void v_multiset(Range& r, Args... args) + void vector_multiset(Range& r, Args... args) { constexpr std::size_t t = sizeof... (args); r.reserve(t); @@ -14,7 +14,7 @@ namespace hack::container } template - void s_multiset(Range& r, Args... args) + void set_multiset(Range& r, Args... args) { (r.insert(args), ...); } diff --git a/src/iterators/associative_ostream_iterator.hpp b/src/iterators/associative_ostream_iterator.hpp new file mode 100644 index 0000000..0a550e2 --- /dev/null +++ b/src/iterators/associative_ostream_iterator.hpp @@ -0,0 +1,39 @@ +#pragma once + +#include + +namespace hack::iterators +{ + template + class associative_ostream_iterator : public std::iterator + { + using traits = std::char_traits; + using ostream_type = std::basic_ostream; + + private: + std::basic_ostream* os; + const std::string devider = ", "; + std::size_t size; + + public: + associative_ostream_iterator(std::size_t size, ostream_type& s) : os { &s }, size { size } { } + + auto& operator=(T const& item) + { + --size; + const auto& [key, value] = item; + *os << "{ " << key << ":" << value << " }" << (size != 0 ? devider : ""); + return *this; + } + + auto& operator*() + { + return *this; + } + + auto& operator++() + { + return *this; + } + }; +} diff --git a/src/iterators/meson.build b/src/iterators/meson.build new file mode 100644 index 0000000..8457fbe --- /dev/null +++ b/src/iterators/meson.build @@ -0,0 +1,14 @@ +headers = ['sequence_ostream_iterator.hpp', 'associative_ostream_iterator.hpp'] +sources = [] + +lib = library( + 'iterators', + include_directories : inc, + install : true, + sources: [headers, sources] +) + +iterators_dep = declare_dependency( + include_directories: inc, + link_with: lib +) diff --git a/src/iterators/sequence_ostream_iterator.hpp b/src/iterators/sequence_ostream_iterator.hpp new file mode 100644 index 0000000..596ebef --- /dev/null +++ b/src/iterators/sequence_ostream_iterator.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include + +namespace hack::iterators +{ + template + class sequence_ostream_iterator : public std::iterator + { + using traits = std::char_traits; + using ostream_type = std::basic_ostream; + + private: + std::basic_ostream* os; + const std::string devider = ", "; + std::size_t size; + + public: + sequence_ostream_iterator(std::size_t size, ostream_type& s) : os { &s }, size { size } { } + + auto& operator=(T const& item) + { + --size; + *os << item << (size != 0 ? devider : ""); + return *this; + } + + auto& operator*() + { + return *this; + } + + auto& operator++() + { + return *this; + } + }; +} diff --git a/src/logger/logger.cpp b/src/logger/logger.cpp new file mode 100644 index 0000000..3981011 --- /dev/null +++ b/src/logger/logger.cpp @@ -0,0 +1,24 @@ +#include "logger.hpp" + +namespace hack +{ + std::string log::devider = " "; + int log::count = 0; + + log::log(const std::string devider, std::experimental::source_location location) : location { location } + { + this->devider = devider; + } + + warn::warn(const std::string devider, std::experimental::source_location location) : location { location } + { + this->devider = devider; + } + + error::error(const std::string devider, std::experimental::source_location location) : location { location } + { + this->devider = devider; + } + + void log::print() { std::cout << std::endl; } +} diff --git a/src/logger/logger.hpp b/src/logger/logger.hpp new file mode 100644 index 0000000..4aa52fb --- /dev/null +++ b/src/logger/logger.hpp @@ -0,0 +1,179 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "view/color.hpp" +#include "iterators/sequence_ostream_iterator.hpp" +#include "iterators/associative_ostream_iterator.hpp" + +namespace hack +{ + template + concept is_sequence_container = 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_string = std::is_convertible_v; + + template + concept is_map = std::same_as> || + std::same_as>; + + class log + { + public: + log(const std::string devider = ", ", std::experimental::source_location location = std::experimental::source_location::current()); + log(log&) = delete; + log(log&&) = delete; + + public: + template + void operator() (const Args&... args) + { + std::cout << make_type_view + << location.file_name() << ":" << view::color::reset + << view::color::italic << view::color::yellow << location.function_name() << "()" << view::color::reset + << view::color::bold << view::color::blue << "[" << location.line() << "]" << view::color::reset << ": "; + count = sizeof...(Args); + print(args...); + } + + private: + std::experimental::source_location location; + static int count; + static std::string devider; + + private: + static void print(); + + static std::ostream& make_type_view(std::ostream &os) + { + os << view::color::bold << view::color::green << "[ok]" << view::color::reset << view::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 : ""); + } + + template + static void print_t(const T& data) + { + std::cout << "{"; + std::copy(data.cbegin(), 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 : ""); + } + + friend class warn; + friend class error; + }; + + class warn : public log + { + public: + warn(const std::string devider = ", ", std::experimental::source_location location = std::experimental::source_location::current()); + warn(log&) = delete; + warn(log&&) = delete; + + public: + template + void operator() (const Args&... args) + { + std::cout << make_type_view + << location.file_name() << ":" << view::color::reset + << view::color::italic << view::color::yellow << location.function_name() << "()" << view::color::reset + << view::color::bold << view::color::blue << "[" << location.line() << "]" << view::color::reset << ": "; + count = sizeof...(Args); + print(args...); + } + + private: + std::experimental::source_location location; + + private: + static std::ostream& make_type_view(std::ostream &os) + { + os << view::color::bold << view::color::yellow << "[WARN]" << view::color::reset << view::color::yellow; + return os; + } + }; + + class error : public log + { + public: + error(const std::string devider = ", ", std::experimental::source_location location = std::experimental::source_location::current()); + error(log&) = delete; + error(log&&) = delete; + + public: + template + void operator() (const Args&... args) + { + std::cout << make_type_view + << location.file_name() << ":" << view::color::reset + << view::color::italic << view::color::yellow << location.function_name() << "()" << view::color::reset + << view::color::bold << view::color::blue << "[" << location.line() << "]" << view::color::reset << ": "; + count = sizeof...(Args); + print(args...); + } + + private: + std::experimental::source_location location; + + private: + static std::ostream& make_type_view(std::ostream &os) + { + os << view::color::bold << view::color::red << "[ERROR]" << view::color::reset << view::color::red; + return os; + } + }; +} diff --git a/src/logger/meson.build b/src/logger/meson.build new file mode 100644 index 0000000..7a05b37 --- /dev/null +++ b/src/logger/meson.build @@ -0,0 +1,14 @@ +headers = ['logger.hpp'] +sources = ['logger.cpp'] + +lib = library( + 'logger', + include_directories : inc, + install : true, + sources: [headers, sources] +) + +logger_dep = declare_dependency( + include_directories: inc, + link_with: lib +) diff --git a/src/meson.build b/src/meson.build index 2e0df30..8a3b66e 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,5 +1,8 @@ inc += include_directories('.') +subdir('view') +subdir('iterators') subdir('string') subdir('range') subdir('container') +subdir('logger') diff --git a/src/view/color.hpp b/src/view/color.hpp new file mode 100644 index 0000000..3f3d37d --- /dev/null +++ b/src/view/color.hpp @@ -0,0 +1,72 @@ +#pragma once + +#include + +namespace hack::view::color +{ + template + std::basic_ostream& reset(std::basic_ostream &os) + { + return os << "\033[0m"; + } + + template + std::basic_ostream& bold(std::basic_ostream &os) + { + return os << "\033[1m"; + } + + template + std::basic_ostream& italic(std::basic_ostream &os) + { + return os << "\033[3m"; + } + + template + std::basic_ostream& black(std::basic_ostream &os) + { + return os << "\033[30m"; + } + + template + std::basic_ostream& red(std::basic_ostream &os) + { + return os << "\033[31m"; + } + + template + std::basic_ostream& green(std::basic_ostream &os) + { + return os << "\033[32m"; + } + + template + std::basic_ostream& yellow(std::basic_ostream &os) + { + return os << "\033[33m"; + } + + template + std::basic_ostream& blue(std::basic_ostream &os) + { + return os << "\033[34m"; + } + + template + std::basic_ostream& magenta(std::basic_ostream &os) + { + return os << "\033[35m"; + } + + template + std::basic_ostream& cyan(std::basic_ostream &os) + { + return os << "\033[36m"; + } + + template + std::basic_ostream& white(std::basic_ostream &os) + { + return os << "\033[37m"; + } +} diff --git a/src/view/meson.build b/src/view/meson.build new file mode 100644 index 0000000..22e3044 --- /dev/null +++ b/src/view/meson.build @@ -0,0 +1,14 @@ +headers = ['color.hpp'] +sources = [] + +lib = library( + 'view', + include_directories : inc, + install : true, + sources: [headers, sources] +) + +view_dep = declare_dependency( + include_directories: inc, + link_with: lib +) diff --git a/tests/container.cpp b/tests/container.cpp index 7895080..612aff3 100644 --- a/tests/container.cpp +++ b/tests/container.cpp @@ -5,6 +5,6 @@ TEST(v_multiset, check) { std::vector v; - hack::container::v_multiset(v, 1, 2, 3); + hack::container::vector_multiset(v, 1, 2, 3); ASSERT_EQ(v.at(0), 1); }