From 507a62912a22189f1852105f7a26cfccbabe37c7 Mon Sep 17 00:00:00 2001 From: Yuanjun Ren Date: Sun, 8 Oct 2023 15:56:27 +0800 Subject: [PATCH] add template testcases --- CMakeLists.txt | 2 +- algorithms/partial_sort_test.cc | 53 +++---- template/basics_test.cc | 207 ++++++++++++++++++++++++++ template/chap_4_variadic_templates.cc | 8 +- 4 files changed, 231 insertions(+), 39 deletions(-) create mode 100644 template/basics_test.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index c20b9ad..69b4e02 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -151,7 +151,7 @@ add_executable(cpp_weekly topics/memory_block_management/memory_block_management_main.cc youtube/cpp_weekly_youtube_test.cc - youtube/e340_string_split_test.cc) + youtube/e340_string_split_test.cc template/basics_test.cc) include_directories(include new_features/cpp_17/inline_variable diff --git a/algorithms/partial_sort_test.cc b/algorithms/partial_sort_test.cc index fd1435b..1635018 100644 --- a/algorithms/partial_sort_test.cc +++ b/algorithms/partial_sort_test.cc @@ -1,6 +1,6 @@ -#include #include #include +#include #include "internal_check_conds.h" @@ -20,31 +20,25 @@ namespace { /// Compare comp); /// \endcode - -void print_res(auto const &s, int middle) -{ +void print_res(auto const &s, int middle) { for (int a : s) std::cout << a << ' '; std::cout << '\n'; - if (middle > 0) - { + if (middle > 0) { while (middle-- > 0) std::cout << "--"; std::cout << '^'; - } - else if (middle < 0) - { - for (auto i = s.size() + middle; --i; std::cout << " ") - {} - for (std::cout << '^'; middle++ < 0; std::cout << "--") - {} + } else if (middle < 0) { + for (auto i = s.size() + middle; --i; std::cout << " ") { + } + for (std::cout << '^'; middle++ < 0; std::cout << "--") { + } } std::cout << '\n'; } -void test1() -{ +void test1() { std::stringstream oss; testing::internal::CaptureStdout(); @@ -80,15 +74,13 @@ void test1() namespace impl { template -void sift_down(RandomIt first, RandomIt last, const Compare &comp) -{ +void sift_down(RandomIt first, RandomIt last, const Compare &comp) { // shift down element at 'first' const auto length = static_cast(last - first); std::size_t current = 0; std::size_t next = 2; - while (next < length) - { + while (next < length) { if (comp(*(first + next), *(first + (next - 1)))) --next; if (!comp(*(first + current), *(first + next))) @@ -103,13 +95,11 @@ void sift_down(RandomIt first, RandomIt last, const Compare &comp) } template -void heap_select(RandomIt first, RandomIt middle, RandomIt last, const Compare &comp) -{ +void heap_select(RandomIt first, RandomIt middle, RandomIt last, + const Compare &comp) { std::make_heap(first, middle, comp); - for (auto i = middle; i != last; ++i) - { - if (comp(*i, *first)) - { + for (auto i = middle; i != last; ++i) { + if (comp(*i, *first)) { std::iter_swap(first, i); sift_down(first, middle, comp); } @@ -117,17 +107,14 @@ void heap_select(RandomIt first, RandomIt middle, RandomIt last, const Compare & } template -void partial_sort_new(RandomIt first, RandomIt middle, RandomIt last, Compare comp) -{ +void partial_sort_new(RandomIt first, RandomIt middle, RandomIt last, + Compare comp) { impl::heap_select(first, middle, last, comp); std::sort_heap(first, middle, comp); } -} +} // namespace impl -} +} // namespace -TEST(partial_sort_test, test1) -{ - test1(); -} \ No newline at end of file +TEST(partial_sort_test, test1) { test1(); } \ No newline at end of file diff --git a/template/basics_test.cc b/template/basics_test.cc new file mode 100644 index 0000000..777277c --- /dev/null +++ b/template/basics_test.cc @@ -0,0 +1,207 @@ +#include "internal_check_conds.h" +#include +#include + +namespace class_variable_alias_templates { + +template class my_vector { +public: + typedef T *my_iterator; + +public: + my_vector(); + + my_vector(T tmp) {} + + my_vector &operator=(const my_vector &item) = default; + +public: + void my_func() { std::cout << "myfunc() is called." << std::endl; } + +public: + my_iterator my_begin() {} + my_iterator my_end() {} +}; + +template my_vector::my_vector() {} + +void test_class_template() { + my_vector tmp_vec; + tmp_vec.my_func(); + + my_vector tmp_vec2(12); +} + +// Deduction Guide +template struct A { + A(T val, T val2) { + std::cout << "A::A(T val, T val2) is called." << std::endl; + } + + A(T val) { std::cout << "A::A(T val) is called." << std::endl; } +}; + +// Deduction Guide +template A(T, T) -> A; + +template +struct B // Aggregate type +{ + T m_b; +}; + +template B(T) -> B; + +void deduction_guide_test() { + A aobj1{15, 16}; + A aobj2{12.8}; + + B bobj1; + B bobj2{15}; + + B bobj3{15}; // Must be deduced with deduction guide +} + +// Partial specialization +template struct TC { + TC() { std::cout << "TC general constructor function" << std::endl; } + + void functest1() { std::cout << "functest1 general version" << std::endl; } +}; + +template <> struct TC { + TC() { + std::cout << "TC fully partial specialization version" + << std::endl; + } + + void functest1(); +}; + +void TC::functest1() { + std::cout << "functest1 partial specialization version" << std::endl; +} + +void partial_specialization_test1() { + TC mytc; + mytc.functest1(); + + TC mytc2; + mytc2.functest1(); +} + +template struct TC { + TC() { + std::cout << "TC partial specialization constructor" << std::endl; + } + + void functest1(); +}; + +template void TC::functest1() { + std::cout << "TC::functest1 partial specialization version" + << std::endl; +} + +void partial_specialization_test2() { + TC mytc4; + mytc4.functest1(); +} + +// Template Template Parameters +template class Container = std::vector> +class my_class { +public: + void func(); + + my_class() { + for (int i = 0; i < 10; ++i) { + myc.push_back(i); + } + } + +public: + Container myc; +}; + +template class Container> +void my_class::func() { + std::cout << "good!" << std::endl; +} + +void template_template_parameter_test() { + my_class mylistobj2; + mylistobj2.func(); +} + +} // namespace class_variable_alias_templates + +TEST(class_template, test1) { + std::stringstream oss; + testing::internal::CaptureStdout(); + + class_variable_alias_templates::test_class_template(); + + auto act_output = testing::internal::GetCapturedStdout(); + + oss << "myfunc() is called.\n"; + +#ifndef NDEBUG + debug_msg(oss, act_output); +#endif + + EXPECT_TRUE(oss.str() == act_output); +} + +TEST(deduction_guide, test1) { + std::stringstream oss; + testing::internal::CaptureStdout(); + + class_variable_alias_templates::deduction_guide_test(); + + auto act_output = testing::internal::GetCapturedStdout(); + + oss << "A::A(T val, T val2) is called.\n" + << "A::A(T val) is called.\n"; + +#ifndef NDEBUG + debug_msg(oss, act_output); +#endif + + EXPECT_TRUE(oss.str() == act_output); +} + +TEST(partial_specialization, test1) { + std::stringstream oss; + testing::internal::CaptureStdout(); + + class_variable_alias_templates::partial_specialization_test1(); + + oss << "TC general constructor function\n" + "functest1 general version\n" + "TC fully partial specialization version\n" + "functest1 partial specialization version\n"; + + auto act_output = testing::internal::GetCapturedStdout(); + +#ifndef NDEBUG + debug_msg(oss, act_output); +#endif + + EXPECT_TRUE(oss.str() == act_output); +} + +TEST(partial_specialization, test2) { + std::stringstream oss; + testing::internal::CaptureStdout(); + + class_variable_alias_templates::partial_specialization_test2(); + + auto act_output = testing::internal::GetCapturedStdout(); + +#ifndef NDEBUG + debug_msg(oss, act_output); +#endif + + EXPECT_TRUE(oss.str() == act_output); +} \ No newline at end of file diff --git a/template/chap_4_variadic_templates.cc b/template/chap_4_variadic_templates.cc index 87f80bb..c182c80 100644 --- a/template/chap_4_variadic_templates.cc +++ b/template/chap_4_variadic_templates.cc @@ -130,11 +130,9 @@ TEST(variadic_templates, using_pack_expasion_test) { derived d3 = true; } -template -auto delay_invoke(F f, Args... args) -{ - return [f = std::move(f), f_args = std::make_tuple(std::move(args)...)]() - -> decltype(auto) { +template auto delay_invoke(F f, Args... args) { + return [f = std::move(f), + f_args = std::make_tuple(std::move(args)...)]() -> decltype(auto) { return std::apply(f, f_args); }; }