This commit is contained in:
chatlanin 2025-01-03 10:58:50 +03:00
parent 55917da5ee
commit 67eab0a97f
15 changed files with 523 additions and 34 deletions

View File

@ -2,12 +2,15 @@
* Это очень нужная коллекция фрагментов рабочего кода для возможного упрощения жизни.* * Это очень нужная коллекция фрагментов рабочего кода для возможного упрощения жизни.*
Автор никоим образом не претендует на чистоту реализации и верность исполнения, поэтому, если вы думаете, что можете сделать это по-другому, то пожалуйста, сделайте это. Автор не претендует на чистоту, реализации и верность исполнения, поэтому, если вы думаете, что можете сделать это по-другому, то пожалуйста, сделайте это.
Я буду очень благодарен вам за предоставленную информацию.
Пожалуйста, смотрите пример реализации с помощью /bin/{package}/main.cpp Пожалуйста, смотрите пример реализации в /bin/main.cpp и tests/...
Тесты пишутся по необходимости и при наличии нужного настроения!!! Что тут:
- concepts - набор разнообразных реализаций концептов
Но вы всегда можете это исправить. :) - iterators - набор разнообразных реализаций итераторов
- log - реализация лдогирования
- patterns - набор различных паттернов проектирования
- utils - вспомогательные решения для библиотеки
- mt - набор математических изысканий

View File

@ -1,10 +1,44 @@
#include <iostream> #include <iostream>
#include <vector>
#include <forward_list>
#include <iostream>
#include "hack/mt/algorithms/sort.hpp"
#include "hack/mt/algorithms/max.hpp"
#include "hack/patterns/ring_buffer.hpp" #include "hack/patterns/ring_buffer.hpp"
auto main(int argc, char *argv[]) -> int auto main(int argc, char *argv[]) -> int
{ {
hack::patterns::ring_buffer<int, 10> rb; // patterns::ring_buffer
for (int i = 1; i < 12; ++i) rb.put(i); {
while(!rb.empty()) std::cout << rb.get().value() << std::endl; hack::patterns::ring_buffer<int, 10> 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<int> v { 4, 4, 6, 1, 4, 3, 2 };
std::forward_list<int> 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;
}
} }

6
run.sh
View File

@ -11,17 +11,17 @@ run() {
# run test [name_test] # run test [name_test]
# example: run test pattrens # example: run test pattrens
if [ $1 = "test" ]; then if [[ "$1" == "test" ]]; then
echo "" echo ""
meson test $2 -C build meson test $2 -C build
echo "" echo ""
awk '/^-------------------------------------------------------------------------------/{flag=1} /===============================================================================/{flag=0} flag' ./build/meson-logs/testlog.txt awk '/^-------------------------------------------------------------------------------/{flag=1} /===============================================================================/{flag=0} flag' ./build/meson-logs/testlog.txt
elif [ $1 = "tests" ]; then elif [[ "$1" == "tests" ]]; then
echo "" echo ""
meson test -C build meson test -C build
echo "" echo ""
# awk '/^-------------------------------------------------------------------------------/{flag=1} /===============================================================================/{flag=0} flag' ./build/meson-logs/testlog.txt # awk '/^-------------------------------------------------------------------------------/{flag=1} /===============================================================================/{flag=0} flag' ./build/meson-logs/testlog.txt
elif [ -d "build" ]; then elif [[ -d "build" ]]; then
run run
else else
command meson setup build command meson setup build

52
src/hack/concepts/concepts.hpp Executable file
View File

@ -0,0 +1,52 @@
#pragma once
#include <vector>
#include <list>
#include <map>
#include <set>
#include <unordered_set>
#include <unordered_map>
#include <forward_list>
#include <concepts>
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;
}

View File

@ -0,0 +1,40 @@
#pragma once
#include <iostream>
namespace hack::iterators
{
template<typename T>
class associative_ostream_iterator
{
using iterator_category = std::output_iterator_tag;
using traits = std::char_traits<char>;
using ostream_type = std::basic_ostream<char, traits>;
private:
std::basic_ostream<char, traits>* 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;
}
};
}

View File

@ -0,0 +1,39 @@
#pragma once
#include <iostream>
namespace hack::iterators
{
template<typename T>
class sequence_ostream_iterator
{
using iterator_category = std::output_iterator_tag;
using traits = std::char_traits<char>;
using ostream_type = std::basic_ostream<char, traits>;
private:
std::basic_ostream<char, traits>* 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;
}
};
}

200
src/hack/log/log.hpp Executable file
View File

@ -0,0 +1,200 @@
#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"
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() << ":" << 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<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 : "");
}
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 : "");
}
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 << 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<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 << view::color::bold << view::color::red << "[ERROR]" << view::color::reset << view::color::red;
return os;
}
};
}

16
src/hack/mt/algorithms/max.hpp Executable file
View File

@ -0,0 +1,16 @@
#pragma once
#include <type_traits>
#include <algorithm>
namespace hack::mt::algorithms
{
// std::common_type_t - делает сравнение по правилу тенарного оператора
// и выводит низводящий возвращающий тип. Т.е. если в качестве одного из
// параметров передалась ссылка, то произойдет низведление до типа ссылки
template<typename T, typename U, typename RT = std::common_type_t<T, U>>
inline RT max(T a, U b)
{
return std::max(a, b);
}
}

View File

@ -0,0 +1,28 @@
#pragma once
#include <algorithm>
namespace hack::mt::algorithms
{
// общая сортировка диапозонов, у кого-то есть своя локалная сортировка, а у кого-то
// нет. А тут чтоб не реализовывать, есть общая.
template<typename Range>
void sort_imp(Range& r, long)
{
std::sort(std::begin(r), std::end(r));
}
template<typename Range, typename = decltype(std::declval<Range&>().sort())>
auto sort_imp(Range& r, int) -> void
{
r.sort();
}
template<typename Range>
void sort(Range& r)
{
sort_imp(r, 0);
}
}

View File

@ -1,4 +1,3 @@
#include <array> #include <array>
#include <mutex> #include <mutex>
#include <optional> #include <optional>

72
src/hack/utils/color.hpp Executable file
View File

@ -0,0 +1,72 @@
#pragma once
#include <iostream>
namespace hack::view::color
{
template<typename CharT, typename Traits>
std::basic_ostream<CharT, Traits>& reset(std::basic_ostream<CharT, Traits> &os)
{
return os << "\033[0m";
}
template<typename CharT, typename Traits>
std::basic_ostream<CharT, Traits>& bold(std::basic_ostream<CharT, Traits> &os)
{
return os << "\033[1m";
}
template<typename CharT, typename Traits>
std::basic_ostream<CharT, Traits>& italic(std::basic_ostream<CharT, Traits> &os)
{
return os << "\033[3m";
}
template<typename CharT, typename Traits>
std::basic_ostream<CharT, Traits>& black(std::basic_ostream<CharT, Traits> &os)
{
return os << "\033[30m";
}
template<typename CharT, typename Traits>
std::basic_ostream<CharT, Traits>& red(std::basic_ostream<CharT, Traits> &os)
{
return os << "\033[31m";
}
template<typename CharT, typename Traits>
std::basic_ostream<CharT, Traits>& green(std::basic_ostream<CharT, Traits> &os)
{
return os << "\033[32m";
}
template<typename CharT, typename Traits>
std::basic_ostream<CharT, Traits>& yellow(std::basic_ostream<CharT, Traits> &os)
{
return os << "\033[33m";
}
template<typename CharT, typename Traits>
std::basic_ostream<CharT, Traits>& blue(std::basic_ostream<CharT, Traits> &os)
{
return os << "\033[34m";
}
template<typename CharT, typename Traits>
std::basic_ostream<CharT, Traits>& magenta(std::basic_ostream<CharT, Traits> &os)
{
return os << "\033[35m";
}
template<typename CharT, typename Traits>
std::basic_ostream<CharT, Traits>& cyan(std::basic_ostream<CharT, Traits> &os)
{
return os << "\033[36m";
}
template<typename CharT, typename Traits>
std::basic_ostream<CharT, Traits>& white(std::basic_ostream<CharT, Traits> &os)
{
return os << "\033[37m";
}
}

View File

@ -1,7 +1,19 @@
inc += include_directories('.') inc += include_directories('.')
headers = [ 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/patterns/ring_buffer.hpp',
'hack/utils/color.hpp'
] ]
sources = [] sources = []

View File

@ -1,20 +0,0 @@
#include <catch2/catch_test_macros.hpp>
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);
}

View File

@ -2,4 +2,5 @@ catch2_with_main_dep = dependency('catch2-with-main')
dep = [hack_dep, catch2_with_main_dep] dep = [hack_dep, catch2_with_main_dep]
test('patterns', executable('patterns', ['patterns/ring_buffer.cpp'], dependencies : dep)) test('patterns', executable('patterns', ['patterns/ring_buffer.cpp'], dependencies : dep))
test('mt', executable('mt', ['mt/max.cpp'], dependencies : dep))

13
tests/mt/max.cpp Normal file
View File

@ -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);
}
}