attachments.h
No OneTemporary

File Metadata

Created
Fri, Mar 13, 9:41 PM

attachments.h

//
// Created by pgess on 3/15/15.
//
#ifndef _XREATE_ATTACHMENTS_H_
#define _XREATE_ATTACHMENTS_H_
#include <map>
#include <assert.h>
#include <type_traits>
namespace xreate
{
//Attachemnt Tags:
struct IsDeclVisited{};
struct IsImplementationOnTheFly{};
//Atachments dictionary
template<class Tag>
struct AttachmentsDict
{
// typedef void Data;
};
template<>
struct AttachmentsDict<IsDeclVisited>
{
typedef bool Data;
static const unsigned int key = 0;
};
template<>
struct AttachmentsDict<IsImplementationOnTheFly>
{
typedef bool Data;
static const unsigned int key = 3;
};
class Symbol;
typedef unsigned int VID;
class AttachmentsImpl
{
friend class SymbolAttachments;
};
//TODO copy function to copy whole data from symbol to symbol: copy(sTo, sFrom);
class SymbolAttachments
{
public:
//TODO add specialization for pointers
template<class Tag>
using Data = typename AttachmentsDict<Tag>::Data;
template<class Tag>
using Input = typename std::conditional<std::is_pointer<Data<Tag>>::value, Data<Tag>, Data<Tag>&&>::type;
template<class Tag>
static typename std::enable_if<std::is_pointer<Data<Tag>>::value>::type
put(const Symbol& symbol, Input<Tag> data)
{
const unsigned int key = AttachmentsDict<Tag>::key;
put(symbol, key, (void*) data);
}
template<class Tag>
static typename std::enable_if<! std::is_pointer<Data<Tag>>::value>::type
put(const Symbol& symbol, Input<Tag> data)
{
const unsigned int key = AttachmentsDict<Tag>::key;
Data<Tag>* holder = new Data<Tag>(data);
put(symbol, key, (void*) holder);
}
/*
template<class Tag>
using Tag2 = std::enable_if<std::is_pointer<Tag>, Tag>::
static void put(const Symbol& symbol, typename AttachmentsDict<Tag>::Data && data)
{
typedef typename AttachmentsDict<Tag>::Data Typ;
Typ* ptr = new Typ(data);
AttachmentsImpl::put(symbol, ptr);
}
*/
template<class Tag>
static typename AttachmentsDict<Tag>::Data& get(const Symbol& symbol, typename AttachmentsDict<Tag>::Data&& valueDefault)
{
typedef typename AttachmentsDict<Tag>::Data Typ;
const unsigned int key = AttachmentsDict<Tag>::key;
Typ* def = new Typ(valueDefault);
Typ* result = static_cast<Typ*> (get(symbol, key, def));
if (result != def) delete def; //TODO check is there some mem leaks?
return *result;
}
template<class Tag>
static typename std::enable_if<std::is_pointer<Data<Tag>>::value, Data<Tag>>::type
get(const Symbol& symbol)
{
const unsigned int key = AttachmentsDict<Tag>::key;
Data<Tag> result = reinterpret_cast<Data<Tag>> (get(symbol, key, nullptr));
assert(result != nullptr); // data not found for the symbol
return result;
}
template<class Tag>
static typename std::enable_if<! std::is_pointer<Data<Tag>>::value, Data<Tag>&>::type
get(const Symbol& symbol)
{
const unsigned int key = AttachmentsDict<Tag>::key;
Data<Tag>* result = reinterpret_cast<Data<Tag>*> (get(symbol, key, nullptr));
assert(result != nullptr); // data not found for the symbol
return *result;
}
template<class Tag>
static bool exists(const Symbol& symbol)
{
const unsigned int key = AttachmentsDict<Tag>::key;
return exists(symbol, key);
}
private:
typedef std::map<VID, void*> Attachment;
std::map<unsigned int, Attachment> __data;
static void put(const Symbol& symbol, unsigned int key, void* data);
static void* get(const Symbol& symbol, unsigned int key, void *def);
static bool exists(const Symbol& symbol, unsigned int key);
};
}
#endif //_XREATE_ATTACHMENTS_H_

Event Timeline