From c6694e386fa3a01bae34991a503b22fb4055e757 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Sat, 18 Aug 2012 14:34:20 +0400 Subject: [PATCH] Add rather inefficient type_identity wrapping for std::set. Accessing an element is O(N), as if it was walking a list. --- library/LuaTypes.cpp | 3 +++ library/include/DataDefs.h | 1 + library/include/DataIdentity.h | 40 ++++++++++++++++++++++++++++++++++ library/xml | 2 +- 4 files changed, 45 insertions(+), 1 deletion(-) diff --git a/library/LuaTypes.cpp b/library/LuaTypes.cpp index 8548c5d0a..53523c3fa 100644 --- a/library/LuaTypes.cpp +++ b/library/LuaTypes.cpp @@ -285,6 +285,9 @@ void container_identity::lua_item_read(lua_State *state, int fname_idx, void *pt void container_identity::lua_item_write(lua_State *state, int fname_idx, void *ptr, int idx, int val_index) { + if (is_readonly()) + field_error(state, fname_idx, "container is read-only", "write"); + auto id = (type_identity*)lua_touserdata(state, UPVAL_ITEM_ID); void *pitem = item_pointer(id, ptr, idx); id->lua_write(state, fname_idx, pitem, val_index); diff --git a/library/include/DataDefs.h b/library/include/DataDefs.h index 7903530dd..ccb29b0e7 100644 --- a/library/include/DataDefs.h +++ b/library/include/DataDefs.h @@ -28,6 +28,7 @@ distribution. #include #include #include +#include #include "Core.h" #include "BitArray.h" diff --git a/library/include/DataIdentity.h b/library/include/DataIdentity.h index dcd0ae979..0f5fd9e7c 100644 --- a/library/include/DataIdentity.h +++ b/library/include/DataIdentity.h @@ -115,6 +115,8 @@ namespace DFHack virtual void lua_item_read(lua_State *state, int fname_idx, void *ptr, int idx); virtual void lua_item_write(lua_State *state, int fname_idx, void *ptr, int idx, int val_index); + virtual bool is_readonly() { return false; } + virtual bool resize(void *ptr, int size) { return false; } virtual bool erase(void *ptr, int index) { return false; } virtual bool insert(void *ptr, int index, void *pitem) { return false; } @@ -343,6 +345,33 @@ namespace df } }; + template + class ro_stl_container_identity : public container_identity { + const char *name; + + public: + ro_stl_container_identity(const char *name, type_identity *item, enum_identity *ienum = NULL) + : container_identity(sizeof(T), &allocator_fn, item, ienum), name(name) + {} + + std::string getFullName(type_identity *item) { + return name + container_identity::getFullName(item); + } + + virtual bool is_readonly() { return true; } + virtual bool resize(void *ptr, int size) { return false; } + virtual bool erase(void *ptr, int size) { return false; } + virtual bool insert(void *ptr, int idx, void *item) { return false; } + + protected: + virtual int item_count(void *ptr, CountMode) { return ((T*)ptr)->size(); } + virtual void *item_pointer(type_identity *item, void *ptr, int idx) { + auto iter = (*(T*)ptr).begin(); + for (; idx > 0; idx--) ++iter; + return (void*)&*iter; + } + }; + class bit_array_identity : public bit_container_identity { public: /* @@ -517,6 +546,10 @@ namespace df static container_identity *get(); }; + template struct identity_traits > { + static container_identity *get(); + }; + template<> struct identity_traits > { static bit_array_identity identity; static bit_container_identity *get() { return &identity; } @@ -579,6 +612,13 @@ namespace df return &identity; } + template + inline container_identity *identity_traits >::get() { + typedef std::set container; + static ro_stl_container_identity identity("set", identity_traits::get()); + return &identity; + } + template inline bit_container_identity *identity_traits >::get() { static bit_array_identity identity(identity_traits::get()); diff --git a/library/xml b/library/xml index 9f91e7476..1eeaa0836 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 9f91e74767b4d583b580d46e16143216ba62ae66 +Subproject commit 1eeaa08360c39a9a2d811544c2443309adc1a8f1