I\'m trying to create container that looks close to how my file spec works. It\'s like a vector but the type of the elements is defined by a hashtable.
If I knew the typ
Given this code:
typedef Toffset uint; //byte offset;
typedef Ttype uint; //enum of types
typedef std::pair member;
typedef std::unordered_map memberdefs;
memberdefs itemKey;
itemKey["a"] = member(0, 0);
itemKey["b"] = member(4, 1);
itemKey["c"] = member(8, 2);
itemKey["d"] = member(12,1);
itemKey["e"] = member(16,3);
itemKey["f"] = member(17,2);
You could read into a char* buffer, and use a simple wrapper class. Still bug-prone and highly confusing. This demo has no iterator (though that would be simple), and requires an external buffer to stay in scope at least as long as the class does.
class interleaved_vector {
const char* buffer;
size_t count;
size_t size;
std::shared_ptr members;
public:
class dynamic_object {
const char* buffer;
std::shared_ptr members;
friend interleaved_vector;
dynamic_object(const char* buffer_, std::shared_ptr members_)
:buffer(buffer_), members(members_)
{}
dynamic_object& operator=(const dynamic_object& b) = delete;
public:
dynamic_object(const dynamic_object& b)
:buffer(b.buffer), members(b.members)
{}
template
T get(const std::string& member) const {
assert((*members)[member].second > 0); //no new members, requires pos sizes
assert((*members)[member].second == sizeof(T));
return *reinterpret_cast(buffer+(*members)[member].first); //technically undefined I think
};
template <>
T* get(const std::string& member) const {
assert((*members)[member].second > 0); //no new members, requires pos sizes
assert((*members)[member].second == sizeof(T));
return reinterpret_cast(buffer+(*members)[member].first); //technically undefined I think
};
void* operator[](const std::string& member) const {
assert((*members)[member].second > 0); //no new members, requires pos sizes
assert((*members)[member].second == sizeof(T));
return reinterpret_cast(buffer+(*members)[member].first); //technically undefined I think
};
};
interleaved_vector(const char* buffer_, size_t count_, size_t size_, const memberdefs& members_)
:buffer(buffer_), count(count_), size(size_), members(members_)
{}
dynamic_object get(size_t index) const {
assert(index
This would allow code such as:
size_t element_size = 32;
size_t num_elements = 1000000
char * buffer = new char[num_elements*element_size];
/*read into buffer*/
interleaved_vector iv(buffer, num_elements, element_size , members);
/*interleaved_vector DOES NOT COPY BUFFER. BUFFER MUST REMAIN IN SCOPE*/
for(int i=0; i(j.first) << '\n';
}
}
This demo code assumes all members are ints (get) but hopefully you can see what's intended.