#include #include #include "generator.h" void* operator new([[maybe_unused]]std::size_t n) { std::cout << "new\n"; throw std::bad_alloc(); } void operator delete(void*) throw() { std::cout << "delete\n"; // Do nothing. actual memory is allocated on the stack } void operator delete(void*, std::size_t) throw() { std::cout << "delete[]\n"; // Do nothing. actual memory is allocated on the stack } template Generator iota(T start) { while(true) { co_yield start++; } } int main() { std::cout << " ** std::string:\n"; { std::string str(15, 'a'); // 15 characters + zero termination - ok str = "123456789012345"; // 15 characters + zero termination - ok try { str = "1234567890123456"; // 16 characters + zero termination } catch(std::bad_alloc &e) { std::cout << "Too big for SSO!\n"; } } std::cout << '\n'; std::cout << " ** std::vector:\n"; { try { std::vector vec{42}; // even one element is too much, no SBO } catch(std::bad_alloc &e) { std::cout << "No SBO for std::vector!\n"; } } std::cout << '\n'; std::cout << " ** std::function:\n"; { { std::function f; char foo[16]{}; f = [foo]() // capture up to 16 bytes is ok for std::function { int i = 0; for(auto v : foo) i += v; return i; }; } // try // this line seem to break gcc... // { // std::function f; // char foo[17]{}; // f = [foo]() // { // int i = 0; // for(auto v : foo) i += v; // return i; // }; // } // catch(std::bad_alloc &e) // { // std::cout << "Too big for SBO in std::function!\n"; // } } std::cout << '\n'; std::cout << " ** co-routines:\n"; { try { auto gen = iota(0); while(true) { auto i = gen(); if(i > 10) break; std::cout << i << " "; } std::cout << '\n'; } catch(std::bad_alloc &e) { std::cout << "Co-routines always allocate!\n"; } } std::cout << '\n'; }