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
296de2c
commit 08b02cc
Showing
3 changed files
with
131 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,54 @@ | ||
// l-value, r-value bindings: | ||
// function parameter call site argument | ||
// l-value to l_value - works (clones the value) | ||
// l-value to r_value - works (clones the value) | ||
// l-value ref to l_value - works | ||
// l-value ref to r_value - does not work | ||
// const l-value ref to l_value - works | ||
// const l-value ref to r_value - works | ||
// const r-value ref - does not make sense most of the time | ||
|
||
// TypeDisplay trick | ||
// reference collapsing | ||
// std::remove_reference<T>::type | ||
|
||
// Write a Value<T> class that uses heap memory for storage! with all ctors and dtors | ||
// initializer_list<T> | ||
// move-ctor, move-assignment | ||
|
||
// a Stack<T> implementation | ||
|
||
#include <iostream> | ||
|
||
using namespace std; // namespace import into our namespace. do not ever use this in a header file! | ||
|
||
// template<typename T> struct RemoveRef { using type = T; }; | ||
// template<typename K> struct RemoveRef<K&> { using type = K; }; | ||
// template<typename K> struct RemoveRef<K&&> { using type = K; }; | ||
|
||
// forward declaration | ||
template<typename T> | ||
struct TypeDisplay; | ||
|
||
using int_ref = int&; | ||
using int_ref_ref = int&&; | ||
|
||
void func(int_ref i) { | ||
|
||
} | ||
|
||
int main(int argc, char* argv[]) | ||
{ | ||
auto i = 5; | ||
func(i); | ||
|
||
// auto t1 = TypeDisplay<int_ref&>{}; // & | ||
// auto t2 = TypeDisplay<int_ref&&>{}; // & | ||
// auto t3 = TypeDisplay<int_ref_ref&>{}; // & | ||
// auto t4 = TypeDisplay<int_ref_ref>{}; // && | ||
|
||
// using K = std::remove_reference<int&&>::type; | ||
// auto k = TypeDisplay<K>{}; | ||
|
||
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,75 @@ | ||
// Write a Value<T> class that uses heap memory for storage! with all ctors and dtors | ||
// move-ctor, move-assignment | ||
|
||
// initializer_list<T> | ||
// a Stack<T> implementation | ||
|
||
#include <iostream> | ||
#include <string> | ||
#include <vector> | ||
|
||
using namespace std; // namespace import into our namespace. do not ever use this in a header file! | ||
|
||
template<typename T> // assume T does not contain any modifiers (no ref, no refref) | ||
struct HeapValue | ||
{ | ||
T* ptr = nullptr; | ||
|
||
// new style c-tor accessible by curly brackets | ||
HeapValue(std::initializer_list<int> content) { | ||
cout << "new ctor is called with a size of " << content.size() << endl; | ||
} | ||
|
||
HeapValue(int) { // old style c-tor | ||
cout << "old ctor is called" << endl; | ||
} | ||
|
||
// default ctor: delegate construction to type T's default ctor: T{} | ||
HeapValue() : ptr(new T{}) { } | ||
|
||
// constructing HeapValue<T> from T types | ||
HeapValue(const T& t) : ptr(new T{t}) { } | ||
|
||
// copy c-tor of HeapValue<T>: clone the right hand side value by delegating to its own copy ctor | ||
HeapValue(const HeapValue<T>& other) : ptr(new T{*other.ptr}) { } | ||
|
||
// r-value ref binding to HeapValue<T>: | ||
// we use this kind of binding for signalling us that right side is a temporary value | ||
HeapValue(HeapValue<T>&& other) | ||
: ptr(other.ptr) // move the treasure of right side to yourself | ||
{ | ||
other.ptr = nullptr; // then mark the right side's treasure pointer as null so that only owner is you | ||
} | ||
|
||
~HeapValue() { | ||
delete ptr; | ||
} | ||
}; | ||
|
||
int main(int argc, char* argv[]) | ||
{ | ||
auto i = HeapValue<int>{}; | ||
|
||
{ | ||
auto j = HeapValue<int>{5}; | ||
} | ||
|
||
auto s = HeapValue<string>{"dhrfbkhdgbkdjgbdkgjfdzkjgn"}; | ||
auto s2 = s; // s2 is being constructed | ||
// auto s3 = HeapValue<string>{string("kjdfbvjhrsbgzsfjhgbzjfhgdbzsjh")}; // move from s2 (steal from s2) | ||
// auto s3 = (HeapValue<string>&&)s2; // move from s2 (steal from s2) | ||
|
||
cout << s2.ptr << endl; | ||
|
||
auto s3 = std::move(s2); // move from s2 (steal from s2) | ||
|
||
cout << s2.ptr << endl; | ||
cout << s3.ptr << endl; | ||
|
||
auto s4 = HeapValue<string>({1, 2, 3, 4, 10, 20}); | ||
// auto v = std::vector<int>{10}; // size is 1 integer. that integer is 10 | ||
// auto v2 = std::vector<int>(10); // size is 10 integers. all integers are default constructed | ||
|
||
|
||
return 0; | ||
} |