forked from furkankirac/cs409-2023-24-spring
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7841eef
commit b53720a
Showing
5 changed files
with
285 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// decltype(auto) | ||
|
||
// get_int_byval(), get_int_byref() | ||
// function object that calls the callable when called :) | ||
|
||
// Tuple struct implementations | ||
|
||
// lambdas capturing local variables: this includes local parameter packs as well | ||
// storing parameter packs: an elegant storage container; get_first, get_size, get_tail impl. | ||
|
||
// std::function<...> // type erasure | ||
|
||
|
||
#include <iostream> | ||
|
||
using namespace std; | ||
|
||
auto get_int_byval() -> int { int i = 5; return i; } | ||
auto get_int_byref() -> int& { static int i = 5; return i; } | ||
|
||
template<typename Callable> | ||
struct FuncObj { | ||
void operator() (Callable callable) { | ||
callable(); | ||
} | ||
}; | ||
|
||
template<typename...> | ||
struct Debug; | ||
|
||
int main() { | ||
|
||
auto value1 = get_int_byval(); // value1 -> int | ||
auto value2 = get_int_byref(); // value2 -> int | ||
|
||
decltype(auto) value3 = get_int_byval(); | ||
decltype(auto) value4 = get_int_byref(); | ||
|
||
// auto func1 = FuncObj< ... >{}; | ||
// decltype(auto) retval = func1(); | ||
|
||
|
||
|
||
// auto t = Debug<decltype(value4)>{}; | ||
|
||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
// tuple implementation | ||
|
||
#include <iostream> | ||
#include <variant> | ||
|
||
using namespace std; | ||
|
||
template<typename First, typename ... Rest> | ||
struct Tuple { | ||
First value; | ||
Tuple<Rest...> rest; | ||
|
||
template<size_t target_idx, size_t current_idx = 0> | ||
auto get() const { | ||
if constexpr(target_idx == current_idx) { | ||
return value; | ||
} else { | ||
return rest.template get<target_idx, current_idx+1>(); | ||
} | ||
} | ||
|
||
template<typename target_type> | ||
auto get() const { | ||
if constexpr(std::is_same_v<target_type, First>) { | ||
return value; | ||
} else { | ||
return rest.template get<target_type>(); | ||
} | ||
} | ||
}; | ||
|
||
template<typename T> | ||
struct Tuple<T> { | ||
T value; | ||
|
||
template<size_t target_idx, size_t current_idx> | ||
auto get() const { | ||
static_assert(target_idx == current_idx, "Index Error"); | ||
return value; | ||
} | ||
|
||
template<typename target_type> | ||
auto get() const { | ||
static_assert(std::is_same_v<target_type, T>, "Type Error"); | ||
return value; | ||
} | ||
}; | ||
|
||
|
||
template<size_t target_idx, typename ... Ts> | ||
auto get(const Tuple<Ts...>& t) { | ||
return t.template get<target_idx>(); | ||
} | ||
|
||
template<typename target_type, typename ... Ts> | ||
auto get(const Tuple<Ts...>& t) { | ||
return t.template get<target_type>(); | ||
} | ||
|
||
|
||
int main() | ||
{ | ||
auto t = Tuple<int, float, double>{2, 1.1f, 3.14}; | ||
|
||
// cout << t.get<3>() << endl; | ||
cout << get<0>(t) << endl; | ||
cout << get<double>(t) << endl; | ||
// cout << t.get<double>() << endl; | ||
|
||
return 0; | ||
} | ||
|
||
|
||
// struct X { | ||
// int i; // assigned 2 | ||
// float f; // assigned 1.1f | ||
// double d; // assigned 1, became 1.0 | ||
|
||
// template<size_t idx> | ||
// auto get() const { | ||
// if constexpr(idx == 0) { | ||
// return i; | ||
// } else if constexpr(idx == 1) { | ||
// return f; | ||
// } else if constexpr(idx == 2) { | ||
// return d; | ||
// } | ||
// } | ||
|
||
// // auto get(size_t index) const -> std::variant<int, float, double> { | ||
// // switch(index) { | ||
// // case 0: return i; | ||
// // case 1: return f; | ||
// // case 2: return d; | ||
// // default: return 0; | ||
// // } | ||
// // } | ||
// }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// tuple and its implementation #2 | ||
|
||
#include <iostream> | ||
#include <tuple> | ||
|
||
using namespace std; | ||
|
||
template<typename First, typename ... Rest> | ||
struct Tuple : Tuple<Rest...> { | ||
static constexpr auto n_elements = sizeof...(Rest) + 1; | ||
|
||
First value; | ||
|
||
template<size_t wanted_index, size_t current_index = n_elements-1> | ||
auto get() const | ||
{ | ||
if constexpr(current_index == wanted_index) | ||
return value; | ||
else | ||
return Tuple<Rest...>::template get<wanted_index, current_index-1>(); | ||
} | ||
}; | ||
|
||
|
||
template<typename Single> | ||
struct Tuple<Single> { | ||
static constexpr auto n_elements = 1; | ||
|
||
Single value; | ||
|
||
template<size_t wanted_index, size_t current_index = n_elements-1> | ||
auto get() const | ||
{ | ||
return value; | ||
} | ||
}; | ||
|
||
|
||
template<size_t index, typename ... Ts> | ||
auto get(const Tuple<Ts...>& t) | ||
{ | ||
return t.template get<index>(); | ||
} | ||
|
||
|
||
struct Foo { | ||
int a1; | ||
int a2; | ||
string a3; | ||
float a4; | ||
int a5; | ||
|
||
Foo(int a1, int a2, string a3, float a4, int a5) : a1{a1}, a2{a2}, a3{a3}, a4{a4}, a5{a5} { } | ||
}; | ||
|
||
int main() | ||
{ | ||
auto t = Tuple<int, float, double>{2.2, 1.1f, 1}; | ||
|
||
cout << t.get<0>() << endl; | ||
cout << get<0>(t) << endl; | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// lambdas capturing local variables: this includes local parameter packs as well | ||
// storing parameter packs: an elegant storage container; get_first, get_size, get_tail impl. | ||
|
||
#include <iostream> | ||
#include <vector> | ||
|
||
using namespace std; | ||
|
||
|
||
auto list(const auto& ... items) { | ||
return [&items...](auto accessor) { | ||
return accessor(items...); | ||
}; | ||
}; | ||
|
||
auto get_first() { | ||
return [](const auto& first, auto ...) { | ||
return first; | ||
}; | ||
} | ||
|
||
auto get_rest() { | ||
return [](const auto&, const auto& ... rest) { | ||
return list(rest...); | ||
}; | ||
} | ||
|
||
auto get_last() { | ||
return [](const auto& ... all) { // all is a parameter pack 100|1|'a'|"abc"|3.14 | ||
return (all, ...); | ||
}; | ||
} | ||
|
||
auto foo() { | ||
auto a = 100; | ||
auto b = 1; | ||
auto c = 'a'; | ||
auto d = "abc"; | ||
auto e = 3.14; | ||
auto l = list(a, b, c, d, e); | ||
return l; | ||
} | ||
|
||
|
||
int main() { | ||
auto v = vector{1, 2, 3, 4}; | ||
|
||
auto z = 'z'; | ||
auto l = list(100, 1, 'a', "abc", 3.14); | ||
|
||
// l is a list instance returned by foo using references to objects that got destructed | ||
// this will cause issues without any warning | ||
// auto l = foo(); | ||
|
||
auto a = l(get_first()); | ||
cout << a << endl; | ||
|
||
auto l_rest = l(get_rest()); | ||
auto b = l_rest(get_first()); | ||
cout << b << endl; | ||
|
||
auto c = l(get_last()); | ||
cout << c << endl; | ||
|
||
// int k = 10; | ||
// auto lambda = [&k](int increment) { k += increment; }; | ||
// lambda(100); | ||
// cout << k << endl; | ||
|
||
return 0; | ||
} |