From b71aec70982902de9ee3474568baf3376f01188a Mon Sep 17 00:00:00 2001 From: Furkan Kirac Date: Sun, 14 Apr 2024 22:42:44 +0300 Subject: [PATCH] Preparation for MT1 --- CMakeLists.txt | 1 + mt1_preparation.cpp | 204 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 205 insertions(+) create mode 100644 mt1_preparation.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index dd25ce8..5e4e23b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,3 +30,4 @@ add_executable(w8a3 "week8-app3.cpp") add_executable(w9a1 "week9-app1.cpp") add_executable(w9a2 "week9-app2.cpp") add_executable(w9a3 "week9-app3.cpp") +add_executable(mt1 "mt1_preparation.cpp") diff --git a/mt1_preparation.cpp b/mt1_preparation.cpp new file mode 100644 index 0000000..297dced --- /dev/null +++ b/mt1_preparation.cpp @@ -0,0 +1,204 @@ +#include +#include +#include +#include +#include +#include + +using namespace std; + +template struct TD; + +template +struct Mat +{ + using type = T; + size_t rows, cols; + vector data; + + Mat(size_t rows = 0, size_t cols = 0, T init = T{}) : rows{rows}, cols{cols}, data(rows*cols, init) { } + + const T* operator[](size_t r) const { return &data[r*cols]; } + T* operator[](size_t r) { return &data[r*cols]; } +}; + +template +void print(const Mat& m) +{ + for(size_t i=0; i) + cout << "\"" << ptr[j] << "\" "; + else + cout << ptr[j] << " "; + } + cout << endl; + } + cout << endl; +} + +template +concept IsMatX = + is_same_v< + Mat::type>, + remove_reference_t + >; + +template +auto transform(T&& mat_src, auto func) +{ + using M = remove_reference_t; // Mat with reference filtered out + using U = typename M::type; // underlying type stored in Mat + using V = remove_cvref_t; // underlying type after the transformation + if constexpr(is_reference_v) + cout << "Transforming l-value parameter" << endl; + else + cout << "Transforming r-value parameter" << endl; + auto mat_dest = Mat{mat_src.rows, mat_src.cols}; + for(size_t i=0; i +requires(IsMatX) +auto inc(T&& input) +{ + if constexpr(is_reference_v) + cout << "Incrementing l-value matrix" << endl; + else + cout << "Incrementing r-value matrix" << endl; + return transform(input, [](auto&& value) { return value+1; }); +} + +template struct concat; +template struct concat { using type = T; }; +template struct concat, tuple> { using type = tuple; }; + +template +using concat_t = typename concat::type; + +template struct IsIntegral : false_type { }; +template<> struct IsIntegral : true_type { }; +template<> struct IsIntegral : true_type { }; +template<> struct IsIntegral : true_type { }; +template<> struct IsIntegral : true_type { }; + +template +struct filter_types; + +template +using filter_types_t = typename filter_types::type; + +template typename FUNC, typename ... FuncTs> +struct filter_types, tuple<>> +{ + using type = void; +}; + +template typename FUNC, typename ... FuncTs, typename First, typename ... Rest> +struct filter_types, tuple> +{ + using type = + concat_t< + conditional_t::value, tuple, tuple<>>, + filter_types_t, tuple> + >; +}; + +struct String : string { using string::string; }; + +template struct Transformer; +template struct Transformer { using type = T; }; +template<> struct Transformer { using type = int; }; +template<> struct Transformer { using type = int; }; +template<> struct Transformer { using type = int; }; +template<> struct Transformer { using type = float; }; +template<> struct Transformer { using type = String; }; + +template +struct transform_types; + +template +using transform_types_t = typename transform_types::type; + +template typename FUNC> +struct transform_types, tuple<>> +{ + using type = void; +}; + +template typename FUNC, typename First, typename ... Rest> +struct transform_types, tuple> +{ + using type = concat_t< tuple::type>, transform_types_t, tuple> >; +}; + + +template typename FUNC, typename ... Ts> +constexpr size_t count_types(const tuple&) +{ + return ((int)FUNC::value + ...); +} + + +int main() +{ + auto m1 = Mat(2, 3, 9.9); // 2 row, 3 column matrix with double values is initialized to 9.9 for each cell + print(m1); + + for(size_t i=0; i>{ + {"pi", 3.14}, + {"CS", "409/509"}, + {"year", 2021} + } + }, [](T&& map_) { + auto s = string{}; + for(const auto& [key, value] : map_) + { + auto value_str = string{}; + if(holds_alternative(value)) + value_str = get(value); + else if(holds_alternative(value)) + value_str = to_string(get(value)); + else if(holds_alternative(value)) + value_str = to_string(get(value)); + s += key + ": " + value_str + " "; + } + return s; + }); + print(m1); + print(m2); + + print(inc(m1)); // prints l-value + print(inc(Mat(1, 4, 1))); // prints r-value + + + using TUPLE = tuple; + + using TUPLE_INTEGRAL = filter_types_t, TUPLE>; + + using TUPLE_FLOATING = filter_types_t, TUPLE>; + + using TUPLE_TRANSFORMED = transform_types_t, TUPLE>; + + cout << "Number of integral types in TUPLE is " << count_types(TUPLE{}) << endl; + cout << "Number of integral types in TUPLE is " << count_types(TUPLE{}) << endl; + cout << "Number of floating types in TUPLE is " << count_types(TUPLE{}) << endl; + + return 0; +}