I do not know any ready-made solution, however, it is not so difficult to do. An array outline might look like this:
#include <cstddef> typedef char saum; // smallest addressable unit of memory namespace magic { template<class T> class IArray { T *const _ptr; const size_t _length; public: operator T* () { return _ptr; } size_t length() const { return _length; } private: IArray<T>(T* ptr, size_t length) : _ptr(ptr), _length(length) {} template<class S, size_t length> friend class Array; }; template<class T> class Generator { public: virtual void operator() (T* place) = 0; }; template<class T, size_t length> class Array { saum buffer[sizeof(T) * length]; public: Array(Generator<T>& generate) { for (size_t i = 0; i < length; i++) generate((T*)buffer + i); } ~Array() { for (size_t i = 0; i < length; i++) ((T*)buffer)[i].~T(); } operator IArray<T> () { return IArray<T>((T*)buffer, length); } operator T* () { return (T*)buffer; } }; }
I'm a little tired, so forgive me not thinking about the best names. However, he must do the job. Perhaps the solution of the generator is not too beautiful, but it gives flexibility. I believe that more feathers will not have a problem.
Example
#include <new> #include <iostream> class Stubborn { public: Stubborn(int value) : value(value*2) { } const int value; private: Stubborn(const Stubborn&); Stubborn& operator=(const Stubborn&); }; struct StubbornGen : public magic::Generator<Stubborn> { StubbornGen() : current_value(0) {} void operator() (Stubborn* place) { new(place) Stubborn(current_value++); } private: int current_value; }; void f(magic::IArray<Stubborn> stubs) { std::cout << stubs[0].value << stubs[1].value << stubs[2].value << stubs[3].value << " " << stubs.length() << std::endl; } int main(int argc, char *argv[]) { StubbornGen gen; magic::Array<Stubborn, 4> stubs(gen); f(stubs); }
Edit: Fixed, thanks to DyP, plus generator settings.
It is important to define the copy constructor and assignment operator for the array in order to avoid the problem indicated by DyP. -- How? - Depends on what you want. Making them private is one way. And making non-small copies is another. - In the second case, the template instance creation mechanism should prevent errors when applying a non-catalyzed class to an Array.
source share