liblinux++

A hosted C++ runtime without any libc.
git clone git://henryandlizzy.uk/liblinux++
Log | Files | Refs

vector.hpp (1515B)


      1 #pragma once
      2 #include "linux.hpp"
      3 
      4 inline void* operator new(size_t, void* p) noexcept
      5 {
      6 	return p;
      7 }
      8 
      9 constexpr size_t next_power_of_two(size_t n)
     10 {
     11 	if (not n)
     12 		return n;
     13 	--n;
     14 	for (unsigned i = 1; i <= 32; i <<= 1)
     15 		n |= n >> i;
     16 	return ++n;
     17 }
     18 
     19 template <typename T>
     20 struct vector
     21 {
     22 	vector() = default;
     23 	~vector()
     24 	{
     25 		for (auto p = buf + used; p != buf; --p)
     26 			p->~T();
     27 		if (buf)
     28 			*munmap(buf, capacity);
     29 	}
     30 	vector(vector const& old)
     31 	{
     32 		reserve(old.size());
     33 		push_back(old);
     34 	}
     35 	vector& operator =(vector const&) = delete; // todo: clear, assign
     36 
     37 	void reserve(size_t min)
     38 	{
     39 		min *= sizeof(T);
     40 		if (min <= capacity)
     41 			return;
     42 		min = min <= 4096u ? 4096u : next_power_of_two(min);
     43 		auto new_buf = reinterpret_cast<T*>(*mmap(nullptr, min, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, {}, 0));
     44 		for (size_t i = 0; i < used; ++i)
     45 		{
     46 			new (new_buf + i) T{buf[i]};
     47 			buf[i].~T();
     48 		}
     49 		if (buf)
     50 			*munmap(buf, capacity);
     51 		buf = new_buf;
     52 		capacity = min;
     53 	}
     54 	void push_back(T c)
     55 	{
     56 		reserve(used + 1);
     57 		new (buf + used++) T{c};
     58 	}
     59 	void push_back(span<T const> data)
     60 	{
     61 		reserve(size() + data.size());
     62 		T* p = buf + used;
     63 		for (auto const& x : data)
     64 			new (p++) T{x};
     65 		used += data.size();
     66 	}
     67 
     68 	T const* data() const { return buf; }
     69 	T* data() { return buf; }
     70 	size_t size() const { return used; }
     71 
     72   operator span<T>() const { return {buf, used}; }
     73   T* begin() { return buf; }
     74   T* end() { return buf + used; }
     75 
     76 private:
     77 	T* buf = nullptr;
     78 	size_t capacity = 0, used = 0;
     79 };