From 67eab0a97f52ae8027b3939fa10f068649a7c406 Mon Sep 17 00:00:00 2001 From: chatlanin Date: Fri, 3 Jan 2025 10:58:50 +0300 Subject: [PATCH] add mt --- README.md | 15 +- bin/main.cpp | 42 +++- run.sh | 6 +- src/hack/concepts/concepts.hpp | 52 +++++ .../associative_ostream_iterator.hpp | 40 ++++ .../iterators/sequence_ostream_iterator.hpp | 39 ++++ src/hack/log/log.hpp | 200 ++++++++++++++++++ src/hack/mt/algorithms/max.hpp | 16 ++ src/hack/mt/algorithms/sort.hpp | 28 +++ src/hack/patterns/ring_buffer.hpp | 1 - src/hack/utils/color.hpp | 72 +++++++ src/meson.build | 12 ++ tests/base_test_fib.cpp | 20 -- tests/meson.build | 1 + tests/mt/max.cpp | 13 ++ 15 files changed, 523 insertions(+), 34 deletions(-) create mode 100755 src/hack/concepts/concepts.hpp create mode 100755 src/hack/iterators/associative_ostream_iterator.hpp create mode 100755 src/hack/iterators/sequence_ostream_iterator.hpp create mode 100755 src/hack/log/log.hpp create mode 100755 src/hack/mt/algorithms/max.hpp create mode 100644 src/hack/mt/algorithms/sort.hpp create mode 100755 src/hack/utils/color.hpp delete mode 100644 tests/base_test_fib.cpp create mode 100644 tests/mt/max.cpp diff --git a/README.md b/README.md index ff4c6c7..3dc3a6c 100755 --- a/README.md +++ b/README.md @@ -2,12 +2,15 @@ * Это очень нужная коллекция фрагментов рабочего кода для возможного упрощения жизни.* -Автор никоим образом не претендует на чистоту реализации и верность исполнения, поэтому, если вы думаете, что можете сделать это по-другому, то пожалуйста, сделайте это. -Я буду очень благодарен вам за предоставленную информацию. +Автор не претендует на чистоту, реализации и верность исполнения, поэтому, если вы думаете, что можете сделать это по-другому, то пожалуйста, сделайте это. -Пожалуйста, смотрите пример реализации с помощью /bin/{package}/main.cpp +Пожалуйста, смотрите пример реализации в /bin/main.cpp и tests/... -Тесты пишутся по необходимости и при наличии нужного настроения!!! - -Но вы всегда можете это исправить. :) +Что тут: +- concepts - набор разнообразных реализаций концептов +- iterators - набор разнообразных реализаций итераторов +- log - реализация лдогирования +- patterns - набор различных паттернов проектирования +- utils - вспомогательные решения для библиотеки +- mt - набор математических изысканий diff --git a/bin/main.cpp b/bin/main.cpp index f9a7762..6dfd177 100644 --- a/bin/main.cpp +++ b/bin/main.cpp @@ -1,10 +1,44 @@ #include +#include +#include +#include + +#include "hack/mt/algorithms/sort.hpp" +#include "hack/mt/algorithms/max.hpp" #include "hack/patterns/ring_buffer.hpp" auto main(int argc, char *argv[]) -> int -{ - hack::patterns::ring_buffer rb; - for (int i = 1; i < 12; ++i) rb.put(i); - while(!rb.empty()) std::cout << rb.get().value() << std::endl; +{ + // patterns::ring_buffer + { + hack::patterns::ring_buffer rb; + for (int i = 1; i < 12; ++i) rb.put(i); + while(!rb.empty()) std::cout << rb.get().value() << std::endl; + } + + // mt::sort + { + std::vector v { 4, 4, 6, 1, 4, 3, 2 }; + std::forward_list l { 8, 7, 5, 9, 0, 1, 3, 2, 6, 4 }; + + hack::mt::algorithms::sort(v); + hack::mt::algorithms::sort(l); + + for (auto d : v) + std::cout << d << " "; + std::cout << std::endl; + + for (auto d : l) + std::cout << d << " "; + std::cout << std::endl; + } + + // mt::max + { + int a = 4, b = 5; + int& c = a; + std::cout << hack::mt::algorithms::max(4, 5) << std::endl; + std::cout << hack::mt::algorithms::max(c, b) << std::endl; + } } diff --git a/run.sh b/run.sh index ec9e74e..dd4589e 100755 --- a/run.sh +++ b/run.sh @@ -11,17 +11,17 @@ run() { # run test [name_test] # example: run test pattrens -if [ $1 = "test" ]; then +if [[ "$1" == "test" ]]; then echo "" meson test $2 -C build echo "" awk '/^-------------------------------------------------------------------------------/{flag=1} /===============================================================================/{flag=0} flag' ./build/meson-logs/testlog.txt -elif [ $1 = "tests" ]; then +elif [[ "$1" == "tests" ]]; then echo "" meson test -C build echo "" # awk '/^-------------------------------------------------------------------------------/{flag=1} /===============================================================================/{flag=0} flag' ./build/meson-logs/testlog.txt -elif [ -d "build" ]; then +elif [[ -d "build" ]]; then run else command meson setup build diff --git a/src/hack/concepts/concepts.hpp b/src/hack/concepts/concepts.hpp new file mode 100755 index 0000000..cc408f8 --- /dev/null +++ b/src/hack/concepts/concepts.hpp @@ -0,0 +1,52 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include + +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; + +} diff --git a/src/hack/iterators/associative_ostream_iterator.hpp b/src/hack/iterators/associative_ostream_iterator.hpp new file mode 100755 index 0000000..223d19a --- /dev/null +++ b/src/hack/iterators/associative_ostream_iterator.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include + +namespace hack::iterators +{ + template + class associative_ostream_iterator + { + using iterator_category = std::output_iterator_tag; + 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& os) : os_ { &os }, size_ { size } { } + + auto& operator=(const T& 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/hack/iterators/sequence_ostream_iterator.hpp b/src/hack/iterators/sequence_ostream_iterator.hpp new file mode 100755 index 0000000..afe78da --- /dev/null +++ b/src/hack/iterators/sequence_ostream_iterator.hpp @@ -0,0 +1,39 @@ +#pragma once + +#include + +namespace hack::iterators +{ + template + class sequence_ostream_iterator + { + using iterator_category = std::output_iterator_tag; + using traits = std::char_traits; + using ostream_type = std::basic_ostream; + + private: + std::basic_ostream* os_; + std::string devider_ = ", "; + std::size_t size_; + + public: + sequence_ostream_iterator(std::size_t size, ostream_type& os) : os_ { &os }, 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/hack/log/log.hpp b/src/hack/log/log.hpp new file mode 100755 index 0000000..4f54f06 --- /dev/null +++ b/src/hack/log/log.hpp @@ -0,0 +1,200 @@ +#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" + +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() << ":" << view::color::reset + << view::color::italic << view::color::yellow << u.function_name() << "()" << view::color::reset + << view::color::bold << view::color::blue << "[" << u.line() << "]" << view::color::reset << ": "; + } + + static void print() { std::cout << std::endl; } + + 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::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 : ""); + } + + 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 << view::color::bold << view::color::yellow << "[WARN]" << view::color::reset << view::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 << view::color::bold << view::color::red << "[ERROR]" << view::color::reset << view::color::red; + return os; + } + }; +} diff --git a/src/hack/mt/algorithms/max.hpp b/src/hack/mt/algorithms/max.hpp new file mode 100755 index 0000000..2f6ab2b --- /dev/null +++ b/src/hack/mt/algorithms/max.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include +#include + +namespace hack::mt::algorithms +{ + // std::common_type_t - делает сравнение по правилу тенарного оператора + // и выводит низводящий возвращающий тип. Т.е. если в качестве одного из + // параметров передалась ссылка, то произойдет низведление до типа ссылки + template> + inline RT max(T a, U b) + { + return std::max(a, b); + } +} diff --git a/src/hack/mt/algorithms/sort.hpp b/src/hack/mt/algorithms/sort.hpp new file mode 100644 index 0000000..2949908 --- /dev/null +++ b/src/hack/mt/algorithms/sort.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include + +namespace hack::mt::algorithms +{ + // общая сортировка диапозонов, у кого-то есть своя локалная сортировка, а у кого-то + // нет. А тут чтоб не реализовывать, есть общая. + template + void sort_imp(Range& r, long) + { + std::sort(std::begin(r), std::end(r)); + } + + template().sort())> + auto sort_imp(Range& r, int) -> void + { + r.sort(); + } + + template + void sort(Range& r) + { + sort_imp(r, 0); + } +} + + diff --git a/src/hack/patterns/ring_buffer.hpp b/src/hack/patterns/ring_buffer.hpp index 50d5f55..84d8ebd 100644 --- a/src/hack/patterns/ring_buffer.hpp +++ b/src/hack/patterns/ring_buffer.hpp @@ -1,4 +1,3 @@ - #include #include #include diff --git a/src/hack/utils/color.hpp b/src/hack/utils/color.hpp new file mode 100755 index 0000000..3f3d37d --- /dev/null +++ b/src/hack/utils/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/meson.build b/src/meson.build index 76e3c7d..46567d2 100755 --- a/src/meson.build +++ b/src/meson.build @@ -1,7 +1,19 @@ inc += include_directories('.') headers = [ + 'hack/concepts/concepts.hpp', + + 'hack/iterators/associative_ostream_iterator.hpp', + 'hack/iterators/sequence_ostream_iterator.hpp', + + 'hack/log/log.hpp', + + 'hack/mt/algorithms/max.hpp', + 'hack/mt/algorithms/sort.hpp', + 'hack/patterns/ring_buffer.hpp', + + 'hack/utils/color.hpp' ] sources = [] diff --git a/tests/base_test_fib.cpp b/tests/base_test_fib.cpp deleted file mode 100644 index 9dcb125..0000000 --- a/tests/base_test_fib.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include - -static int Factorial(int number) -{ - // return number <= 1 ? number : Factorial(number - 1) * number; // fail - return number <= 1 ? 1 : Factorial(number - 1) * number; // pass -} - -TEST_CASE("[base_test_fib] Factorial of 0 is 1 (fail)", "[single-file]") -{ - REQUIRE(Factorial(0) == 1); -} - -TEST_CASE("[base_test_fib] Factorials of 1 and higher are computed (pass)", "[single-file]") -{ - REQUIRE(Factorial(1) == 1); - REQUIRE(Factorial(2) == 2); - REQUIRE(Factorial(3) == 6); - REQUIRE(Factorial(10) == 3628800); -} diff --git a/tests/meson.build b/tests/meson.build index 14e8b04..6a32200 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -2,4 +2,5 @@ catch2_with_main_dep = dependency('catch2-with-main') dep = [hack_dep, catch2_with_main_dep] test('patterns', executable('patterns', ['patterns/ring_buffer.cpp'], dependencies : dep)) +test('mt', executable('mt', ['mt/max.cpp'], dependencies : dep)) diff --git a/tests/mt/max.cpp b/tests/mt/max.cpp new file mode 100644 index 0000000..93256b4 --- /dev/null +++ b/tests/mt/max.cpp @@ -0,0 +1,13 @@ +#include "catch2/catch_test_macros.hpp" +#include "hack/mt/algorithms/max.hpp" + +TEST_CASE("mt") +{ + SECTION("max buffer") + { + int a = 4, b = 5; + int& c = a; + REQUIRE(hack::mt::algorithms::max(4, 5) == 5); + REQUIRE(hack::mt::algorithms::max(c, b) == 5); + } +}