summaryrefslogtreecommitdiff
path: root/a6/stack_new.cc
diff options
context:
space:
mode:
Diffstat (limited to 'a6/stack_new.cc')
-rw-r--r--a6/stack_new.cc139
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';
+
+}