diff options
Diffstat (limited to 'a6/stack_new.cc')
-rw-r--r-- | a6/stack_new.cc | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/a6/stack_new.cc b/a6/stack_new.cc new file mode 100644 index 0000000..49f234f --- /dev/null +++ b/a6/stack_new.cc @@ -0,0 +1,139 @@ +#include <iostream> +#include <string> +#include <functional> +#include <stdexcept> + +#include "generator.h" + +// Universal allocator +namespace memory +{ + void* ptr{}; + std::size_t n{}; +} + +void* operator new(std::size_t n)// throw(std::bad_alloc) +{ + std::cout << "new (" << n << " bytes from " + << memory::ptr << " which is size " << memory::n << ")\n"; + + if(memory::ptr == nullptr) throw std::bad_alloc(); + if(n > memory::n) throw std::bad_alloc(); + + auto ptr = memory::ptr; + memory::ptr = nullptr; // use only once + memory::n = 0; + + return ptr; +} + +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<std::size_t S, typename T = char> +class StackNew +{ +public: + StackNew() + { + std::cout << "StackNew ptr=" << (void*)buf + << " of size " << S * sizeof(T) << '\n'; + memory::ptr = buf; + memory::n = S * sizeof(T); + } + +private: + T buf[S]; +}; + +template<typename T> +Generator<T> iota(T start) +{ + while(true) + { + co_yield start++; + } +} + +int main() +{ + std::cout << " ** std::string:\n"; + { + StackNew<100> buffer; + std::string str{"hello allocating string world"}; + + try + { + str.reserve(50); // no stack buffer supplied so throws std::bad_alloc + } + catch(std::bad_alloc &e) + { + std::cout << "Stack buffer missing!\n"; + } + } + std::cout << '\n'; + + + std::cout << " ** std::vector:\n"; + { + StackNew<10, int> buffer; + std::vector<int> vec{1,2,3,4,5,6,7,8,9,10}; + + StackNew<20, int> buffer2; + try + { + vec.resize(21); // throws std::bad_alloc + } + catch(std::bad_alloc &e) + { + std::cout << "Stack buffer was too small!\n"; + } + } + std::cout << '\n'; + + + std::cout << " ** std::function:\n"; + { + std::function<int()> f; + { + StackNew<32> buffer; + char foo[32]{}; + f = [foo]() + { + int i = 0; + for(auto v : foo) + { + i += v; + } + return i; + }; + } + [[maybe_unused]]auto x = f(); + } + std::cout << '\n'; + + + std::cout << " ** co-routines:\n"; + { + StackNew<100> buffer; + auto gen = iota(0); + while(true) + { + auto i = gen(); + if(i > 10) break; + std::cout << i << " "; + } + std::cout << '\n'; + } + std::cout << '\n'; + +} |