parent
fff182b457
commit
cc3bb171e1
@ -1,4 +1,4 @@ |
|||||||
#include "coro.hpp" |
#include "../coro.hpp" |
||||||
#include <coroutine> |
#include <coroutine> |
||||||
#include <vector> |
#include <vector> |
||||||
#include <iostream> |
#include <iostream> |
@ -1,5 +1,5 @@ |
|||||||
#include <fmt/core.h> |
#include <fmt/core.h> |
||||||
#include "fsm.hpp" |
#include "../fsm.hpp" |
||||||
|
|
||||||
using namespace fmt; |
using namespace fmt; |
||||||
|
|
@ -0,0 +1,23 @@ |
|||||||
|
executable('regtest', 'regtest.cpp', |
||||||
|
dependencies: [fmt]) |
||||||
|
|
||||||
|
executable('audiotest', 'audiotest.cpp', |
||||||
|
dependencies: dependencies) |
||||||
|
|
||||||
|
executable('jsontest', 'jsontest.cpp', |
||||||
|
dependencies: dependencies) |
||||||
|
|
||||||
|
executable('threadtest', 'threadtest.cpp', |
||||||
|
dependencies: dependencies) |
||||||
|
|
||||||
|
executable('fsmtest', 'fsmtest.cpp', |
||||||
|
dependencies: dependencies) |
||||||
|
|
||||||
|
executable('badref', 'badref.cpp', |
||||||
|
dependencies: dependencies) |
||||||
|
|
||||||
|
executable('corotest', [ |
||||||
|
'corotest.cpp' |
||||||
|
], |
||||||
|
dependencies: dependencies, |
||||||
|
cpp_args: '-fcoroutines') |
@ -0,0 +1,130 @@ |
|||||||
|
#include <cassert> |
||||||
|
#include <cstdio> |
||||||
|
#include <fstream> |
||||||
|
#include <iostream> |
||||||
|
#include <locale> |
||||||
|
#include <memory> |
||||||
|
#include <stdexcept> |
||||||
|
|
||||||
|
// helper class for runtime polymorphism demo below
|
||||||
|
struct B |
||||||
|
{ |
||||||
|
virtual ~B() = default; |
||||||
|
|
||||||
|
virtual void bar() { std::cout << "B::bar\n"; } |
||||||
|
}; |
||||||
|
|
||||||
|
struct D : B |
||||||
|
{ |
||||||
|
D() { std::cout << "D::D\n"; } |
||||||
|
~D() { std::cout << "D::~D\n"; } |
||||||
|
|
||||||
|
void bar() override { std::cout << "D::bar\n"; } |
||||||
|
}; |
||||||
|
|
||||||
|
// a function consuming a unique_ptr can take it by value or by rvalue reference
|
||||||
|
std::unique_ptr<D> pass_through(std::unique_ptr<D> p) |
||||||
|
{ |
||||||
|
p->bar(); |
||||||
|
return p; |
||||||
|
} |
||||||
|
|
||||||
|
// helper function for the custom deleter demo below
|
||||||
|
void close_file(std::FILE* fp) |
||||||
|
{ |
||||||
|
std::fclose(fp); |
||||||
|
} |
||||||
|
|
||||||
|
// unique_ptr-based linked list demo
|
||||||
|
struct List |
||||||
|
{ |
||||||
|
struct Node |
||||||
|
{ |
||||||
|
int data; |
||||||
|
std::unique_ptr<Node> next; |
||||||
|
}; |
||||||
|
|
||||||
|
std::unique_ptr<Node> head; |
||||||
|
|
||||||
|
~List() |
||||||
|
{ |
||||||
|
// destroy list nodes sequentially in a loop, the default destructor
|
||||||
|
// would have invoked its `next`'s destructor recursively, which would
|
||||||
|
// cause stack overflow for sufficiently large lists.
|
||||||
|
while (head) |
||||||
|
{ |
||||||
|
auto next = std::move(head->next); |
||||||
|
head = std::move(next); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void push(int data) |
||||||
|
{ |
||||||
|
head = std::unique_ptr<Node>(new Node{data, std::move(head)}); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
int main() |
||||||
|
{ |
||||||
|
std::cout << "1) Unique ownership semantics demo\n"; |
||||||
|
{ |
||||||
|
// Create a (uniquely owned) resource
|
||||||
|
std::unique_ptr<D> p = std::make_unique<D>(); |
||||||
|
|
||||||
|
// Transfer ownership to `pass_through`,
|
||||||
|
// which in turn transfers ownership back through the return value
|
||||||
|
std::unique_ptr<D> q = pass_through(std::move(p)); |
||||||
|
|
||||||
|
// p is now in a moved-from 'empty' state, equal to nullptr
|
||||||
|
assert(!p); |
||||||
|
} |
||||||
|
|
||||||
|
std::cout << "\n" "2) Runtime polymorphism demo\n"; |
||||||
|
{ |
||||||
|
// Create a derived resource and point to it via base type
|
||||||
|
std::unique_ptr<B> p = std::make_unique<D>(); |
||||||
|
|
||||||
|
// Dynamic dispatch works as expected
|
||||||
|
p->bar(); |
||||||
|
} |
||||||
|
|
||||||
|
std::cout << "\n" "3) Custom deleter demo\n"; |
||||||
|
std::ofstream("demo.txt") << 'x'; // prepare the file to read
|
||||||
|
{ |
||||||
|
using unique_file_t = std::unique_ptr<std::FILE, decltype(&close_file)>; |
||||||
|
unique_file_t fp(std::fopen("demo.txt", "r"), &close_file); |
||||||
|
if (fp) |
||||||
|
std::cout << char(std::fgetc(fp.get())) << '\n'; |
||||||
|
} // `close_file()` called here (if `fp` is not null)
|
||||||
|
|
||||||
|
std::cout << "\n" "4) Custom lambda-expression deleter and exception safety demo\n"; |
||||||
|
try |
||||||
|
{ |
||||||
|
std::unique_ptr<D, void(*)(D*)> p(new D, [](D* ptr) |
||||||
|
{ |
||||||
|
std::cout << "destroying from a custom deleter...\n"; |
||||||
|
delete ptr; |
||||||
|
}); |
||||||
|
|
||||||
|
throw std::runtime_error(""); // `p` would leak here if it were a plain pointer
|
||||||
|
} |
||||||
|
catch (const std::exception&) |
||||||
|
{ |
||||||
|
std::cout << "Caught exception\n"; |
||||||
|
} |
||||||
|
|
||||||
|
std::cout << "\n" "5) Array form of unique_ptr demo\n"; |
||||||
|
{ |
||||||
|
std::unique_ptr<D[]> p(new D[3]); |
||||||
|
} // `D::~D()` is called 3 times
|
||||||
|
|
||||||
|
std::cout << "\n" "6) Linked list demo\n"; |
||||||
|
{ |
||||||
|
List wall; |
||||||
|
const int enough{1'000'000}; |
||||||
|
for (int beer = 0; beer != enough; ++beer) |
||||||
|
wall.push(beer); |
||||||
|
|
||||||
|
std::cout << enough << " bottles of beer on the wall...\n"; |
||||||
|
} // destroys all the beers
|
||||||
|
} |
Loading…
Reference in new issue