parent
fff182b457
commit
cc3bb171e1
@ -1,4 +1,4 @@ |
||||
#include "coro.hpp" |
||||
#include "../coro.hpp" |
||||
#include <coroutine> |
||||
#include <vector> |
||||
#include <iostream> |
@ -1,5 +1,5 @@ |
||||
#include <fmt/core.h> |
||||
#include "fsm.hpp" |
||||
#include "../fsm.hpp" |
||||
|
||||
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