Учитывая этот код:
typedef Toffset uint; //byte offset;
typedef Ttype uint; //enum of types
typedef std::pair<Toffset,Ttype> member;
typedef std::unordered_map<std::string, member> 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);
Вы можете читать в буфер char * и использовать простой класс-оболочку. Все еще подвержен ошибкам и очень запутанный. Эта демонстрация не имеет итератора (хотя это было бы просто) и требует, чтобы внешний буфер оставался в области действия хотя бы до тех пор, пока класс делает это.
class interleaved_vector {
const char* buffer;
size_t count;
size_t size;
std::shared_ptr<memberdefs> members;
public:
class dynamic_object {
const char* buffer;
std::shared_ptr<memberdefs> members;
friend interleaved_vector;
dynamic_object(const char* buffer_, std::shared_ptr<memberdefs> 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 <class T>
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<T*>(buffer+(*members)[member].first); //technically undefined I think
};
template <>
T* get<T*>(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<T*>(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<void*>(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<count);
return dynamic_object(buffer + size*index, members);
}
dynamic_object operator[](size_t index) const {
assert(index<count);
return dynamic_object(buffer + size*index, members);
}
size_t size() {
return count;
}
};
Это позволило бы код, такой как:
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<iv.size(); ++i) {
for(memberdefs::const_iterator j=members.begin(); j!=members.end(); ++j) {
dynamic_object ob = iv[i];
std::cout << "data[" << i << "]." << j.first << " = ";
std::cout << ob.get<int>(j.first) << '\n';
}
}
В этом демонстрационном коде предполагается, что все участники являются целыми числами (получить), но, надеюсь, вы сможете увидеть, что предполагается.