#include <cstddef>
#include <utility>
#include <iterator>
#include <cassert>
#include <iostream>

template <typename T, std::size_t N>
class InplaceVector {
	private:
		union Container {
			constexpr Container () {}
			T obj;
		};
	public:
		using reference = T&;
		
		class iterator {
			public:
			    using iterator_category = std::random_access_iterator_tag;
				using value_type = T;
	
				explicit constexpr iterator(Container* ptr) : ptr(ptr) {}
				iterator (const iterator&) = default;
				iterator (iterator&&) = default;
				
				iterator& operator++() { ++ptr; return *this; }
				iterator operator++(int) { iterator retval = *this; ++(*this); return retval; }
				bool operator==(const iterator& other) const { return ptr == other.ptr; }
				bool operator!=(const iterator& other) const { return !(*this == other); }
				reference operator*() const { return ptr->obj; }
			private:
				Container* ptr;
		};
		
		constexpr InplaceVector () : fill (0), data_ {} {}
		InplaceVector (const InplaceVector& src) : fill (0) {
			for (std::size_t i = 0; i < src.fill; ++i) {
				new (&data_ [i].obj) T (src.data_ [i].obj);
				++fill;
			}
		}
		
		// Not exception save
		InplaceVector (InplaceVector&& src) : fill (src.fill) {
			for (std::size_t i = 0; i < src.fill; ++i) {
				new (&data_ [i].obj) T (std::move (src.data_ [i].obj));
				++fill;
			}
			src.fill = 0;
		}
		
		
		~InplaceVector () { clear (); }
		
		template <typename... Args >
		reference emplace_back (Args&&... args) {
			assert (fill < N);
			T* res = new (&data_ [fill].obj) T (std::forward<Args> (args)...);
			++fill;
			return *res;
		}
		
		void pop_back () {
			assert (fill);
			data_ [fill - 1].obj.~T ();
			--fill;
		}
		
		std::size_t size () const { return fill; }
		
		void clear () {
			for (; fill; --fill) {
				data_ [fill - 1].obj.~T ();
			}
		}
		
		reference operator [] (std::size_t i) {
			assert (i < fill);
			return data_ [i].obj;
		}
		
		iterator begin() { return iterator { data_ }; }
		iterator end() { return iterator { data_ + fill }; }
		
	private:
		Container data_ [N];
		std::size_t fill;
};


class Counter {
private:
    int count;
public:
    Counter() : count(0) {}  // Constructor initializes count to 0
    void exec() {
        count++;
    }
    int getCount() const {
        return count;
    }
};
class Counter_IF {
private:
    Counter counterInstance;  // Instance of Counter
public:
	Counter_IF () {}
	
    void exec() {
        counterInstance.exec();  // Call exec on the Counter instance
    }
    int getCount() const {
        return counterInstance.getCount();  // Retrieve count from the Counter instance
    }
};

static InplaceVector<Counter_IF, 8> counters;
int main() {

   // Zaeher anlegen
    for(std::size_t idx=0;idx<5;idx++) counters.emplace_back ();
    // Zaehler laufen lassen
    for(Counter_IF& c : counters) c.exec();
	
	counters.clear ();
	
    // Zaeher new anlegen
    for(std::size_t idx=0;idx<8;idx++) counters.emplace_back ();
    // Zaehler laufen lassen
    for(Counter_IF& c : counters) c.exec();
	
    // Anzeigen
    for(std::size_t idx=0;idx<counters.size ();idx++)
    {
        std::cout << "Counter " << idx << " count: " << counters[idx].getCount() << std::endl;
    }
	
    return 0;
}