template<typename T> class Deque : public ContainerRenderAdapter, public ContainerInterface, public std::deque<T>, public ContainerDataAttach<T> {
public:
	virtual int GetSize() {
		return this->size();
	}

#ifdef BUILDING_INSPECTOR

	struct _ImGui_Getter_Ctx {
		char namebuf[16];
	};

	inline static bool _ImGui_Getter(void* pd, int idx, const char** outn) {
		_ImGui_Getter_Ctx* ctx = (_ImGui_Getter_Ctx*)pd;
		sprintf(ctx->namebuf, "[%d]", idx);
		*outn = ctx->namebuf;
		return true;
	}

	virtual void _RenderInspector(const char* pMem, const char* pimID, 
		MetaClassDescription** ppOutSelectedType, void** pOutSelectedInst, const char** n, u32* s, int* oidx) override {
		_ImGui_Getter_Ctx ctx{};

		*n = "Deque";
		*s = this->GetSize();
		*ppOutSelectedType = mpContainerDataType;
		ImGui::ListBox(pimID, oidx, &_ImGui_Getter, (void*)&ctx, (int) * s);

		if (*s) {

			auto selectedIt = this->begin();
			std::advance(selectedIt, *oidx);
			*pOutSelectedInst = (void*) & (*selectedIt);

		}
	}

#endif

	//no need for serialize main

	static MetaOpResult MetaOperation_SerializeAsync(void* pObj,
		MetaClassDescription* pDesc, MetaMemberDescription* mCtx, void* pUserData) {
		Deque<T>* array = static_cast<Deque<T>*>(pObj);
		MetaClassDescription* vtype = ::GetMetaClassDescription(typeid(T).name());
		if (!array || !vtype)return eMetaOp_Fail;
		MetaOperation op = vtype->GetOperationSpecialization(74);
		if (!op)op = Meta::MetaOperation_SerializeAsync;
		unsigned int size = array->GetSize();
		static_cast<MetaStream*>(pUserData)->serialize_uint32(&size);
		for (int i = 0; i < size; i++) {
			if (static_cast<MetaStream*>(pUserData)->mMode == MetaStreamMode::eMetaStream_Write) {
				const T v = array->operator[](i);
				if (op((void*)&v, vtype, NULL, pUserData) != eMetaOp_Succeed)return eMetaOp_Fail;
			}
			else {
				T value = T();
				if (op(&value, vtype, NULL, pUserData) != eMetaOp_Succeed)return eMetaOp_Fail;
				array->AddElement(0, NULL, &value);//OK, since its a copy
			}
		}
		return eMetaOp_Succeed;
	}

	INLINE virtual bool KeyedContainer() { return false; }
	INLINE virtual void* GetKey(int) { return NULL; }

	virtual MetaClassDescription* GetContainerKeyClassDescription() {
		return NULL;
	}

	virtual MetaClassDescription* GetContainerDataClassDescription() {
		return mpContainerDataType;
	}

	const T operator[](int at_index) {
		int i = 0;
		for (auto it = this->begin(); it != this->end(); it++, i++) {
			if (i == at_index) {
				return *it;
				break;
			}
		}
		return *(T*)NULL;
	}

	INLINE virtual bool IsResizable() { return true; }

	virtual bool AllocateElements(int total) {
		return false;
	}

	virtual void ClearElements() {
		this->clear();
	}

	virtual void RemoveElement(int at_index) {
		int i = 0;
		for (auto it = this->begin(); it != this->end(); it++, i++) {
			if (i == at_index) {
				this->erase(it);
				break;
			}
		}
	}

	virtual void AddElement(int at_index, const void* pKeyData, void* pValueToAdd) {
		this->push_back(*(T*)pValueToAdd);
	}

	//DO NOT USE THIS IN DEQUES (NOT IMPLEMENTED)!
	virtual void SetElement(int at_index, const void* pKeyData, void* pValue) {}

	//DO NOT USE THIS IN DEQUES (NOT IMPLEMENTED)!
	virtual String* GetElementName(String* result, int index) {
		return NULL;
	}

	//DO NOT USE THIS IN DEQUES (NOT IMPLEMENTED)!
	virtual void* GetElement(int at_index) {
		return NULL;
	}
};

#endif