diff options
| -rw-r--r-- | slicer/slicer/enumMap.h | 66 | ||||
| -rw-r--r-- | slicer/slicer/modelPartsTypes.h | 4 | ||||
| -rw-r--r-- | slicer/slicer/modelPartsTypes.impl.h | 33 | ||||
| -rw-r--r-- | slicer/tool/parser.cpp | 20 | 
4 files changed, 91 insertions, 32 deletions
diff --git a/slicer/slicer/enumMap.h b/slicer/slicer/enumMap.h new file mode 100644 index 0000000..98ecd04 --- /dev/null +++ b/slicer/slicer/enumMap.h @@ -0,0 +1,66 @@ +#ifndef SLICER_ENUM_MAP_H +#define SLICER_ENUM_MAP_H + +namespace Slicer { +	enum class EnumMapKey { +		Value, +		Name, +	}; + +	template<typename E> class EnumMap { +	public: +		struct Node { +			E value; +			std::string_view name; +			const std::string * nameStr; +		}; + +		template<EnumMapKey Key, typename T> +		constexpr inline const Node * +		find(const T & v) const +		{ +			auto b = begin(); +			const auto e = end(); +			while (b != e) { +				if constexpr (Key == EnumMapKey::Value) { +					if (b->value == v) { +						return b; +					} +				} +				else if constexpr (Key == EnumMapKey::Name) { +					if (b->name == v) { +						return b; +					} +				} +				++b; +			} +			return nullptr; +		} + +		virtual constexpr const Node * begin() const = 0; +		virtual constexpr const Node * end() const = 0; +	}; + +	template<typename E, std::size_t N> class EnumMapImpl : public EnumMap<E> { +	public: +		using NodeType = typename EnumMap<E>::Node; +		template<std::size_t n> using Arr = std::array<NodeType, n>; + +		constexpr const NodeType * +		begin() const override +		{ +			return arr.begin(); +		} + +		constexpr const NodeType * +		end() const override +		{ +			return arr.end(); +		} + +		inline constexpr EnumMapImpl(Arr<N> a) : arr(std::move(a)) { } +		const Arr<N> arr; +	}; +} + +#endif diff --git a/slicer/slicer/modelPartsTypes.h b/slicer/slicer/modelPartsTypes.h index 78eee3b..062d9c2 100644 --- a/slicer/slicer/modelPartsTypes.h +++ b/slicer/slicer/modelPartsTypes.h @@ -225,11 +225,11 @@ namespace Slicer {  		ModelPartType GetType() const override;  		static const ModelPartType type;  	}; +	template<typename T> class EnumMap;  	template<typename T> class DLL_PUBLIC ModelPartForEnum : public ModelPartForEnumBase, protected ModelPartModel<T> {  	public:  		using element_type = T; -		class DLL_PRIVATE Enumerations;  		explicit ModelPartForEnum(T * s); @@ -240,7 +240,7 @@ namespace Slicer {  		bool GetValue(ValueTarget && s) override;  		static const Metadata metadata; -		static const Enumerations enumerations; +		static constexpr const EnumMap<T> & enumerations();  		DLL_PUBLIC static const std::string & lookup(T);  		DLL_PUBLIC static T lookup(const std::string_view &);  	}; diff --git a/slicer/slicer/modelPartsTypes.impl.h b/slicer/slicer/modelPartsTypes.impl.h index 7efc02d..b79a141 100644 --- a/slicer/slicer/modelPartsTypes.impl.h +++ b/slicer/slicer/modelPartsTypes.impl.h @@ -2,6 +2,7 @@  #define SLICER_MODELPARTSTYPES_IMPL_H  #include "common.h" +#include "enumMap.h"  #include "modelPartsTypes.h"  #include <Ice/StreamHelpers.h>  #include <IceUtil/Optional.h> @@ -659,18 +660,6 @@ namespace Slicer {  	}  	// ModelPartForEnum -	template<typename T> using EnumPair = std::pair<T, std::string>; - -	template<typename T> -	class ModelPartForEnum<T>::Enumerations : -		public boost::multi_index_container<EnumPair<T>, -				boost::multi_index::indexed_by<boost::multi_index::ordered_unique<boost::multi_index::member< -													   EnumPair<T>, const T, &EnumPair<T>::first>>, -						boost::multi_index::ordered_unique< -								boost::multi_index::member<EnumPair<T>, const std::string, &EnumPair<T>::second>, -								std::less<>>>> { -	}; -  	template<typename T> ModelPartForEnum<T>::ModelPartForEnum(T * s) : ModelPartModel<T>(s) { }  	template<typename T> @@ -680,14 +669,12 @@ namespace Slicer {  		return metadata;  	} -	template<int Side, typename Ex, typename ExP, typename T, typename V, typename R> -	inline const auto & -	ModelPartForEnumLookup( -			const typename ModelPartForEnum<T>::Enumerations & enumerations, const V & val, R EnumPair<T>::*rv) +	template<EnumMapKey Key, typename Ex, typename ExP, typename T, typename V> +	inline const auto * +	ModelPartForEnumLookup(const EnumMap<T> & enumerations, const V & val)  	{ -		const auto & side = enumerations.template get<Side>(); -		if (auto i = side.find(val); i != side.end()) { -			return (*i).*rv; +		if (auto i = enumerations.template find<Key>(val)) { +			return i;  		}  		throw Ex(ExP(val), typeid(T).name());  	} @@ -696,16 +683,16 @@ namespace Slicer {  	T  	ModelPartForEnum<T>::lookup(const std::string_view & val)  	{ -		return ModelPartForEnumLookup<1, InvalidEnumerationSymbol, std::string, T>( -				enumerations, val, &EnumPair<T>::first); +		return ModelPartForEnumLookup<EnumMapKey::Name, InvalidEnumerationSymbol, std::string, T>(enumerations(), val) +				->value;  	}  	template<typename T>  	const std::string &  	ModelPartForEnum<T>::lookup(T val)  	{ -		return ModelPartForEnumLookup<0, InvalidEnumerationValue, ::Ice::Int, T>( -				enumerations, val, &EnumPair<T>::second); +		return *ModelPartForEnumLookup<EnumMapKey::Value, InvalidEnumerationValue, ::Ice::Int, T>(enumerations(), val) +						->nameStr;  	}  	template<typename T> diff --git a/slicer/tool/parser.cpp b/slicer/tool/parser.cpp index 5a1d626..5951d54 100644 --- a/slicer/tool/parser.cpp +++ b/slicer/tool/parser.cpp @@ -420,15 +420,21 @@ namespace Slicer {  		copyMetadata(e->getMetaData());  		fprintbf(cpp, ";\n\n"); -		fprintbf(cpp, -				"template<> DLL_PUBLIC\nconst ModelPartForEnum< %s >::Enumerations\nModelPartForEnum< %s " -				">::enumerations([]() -> ModelPartForEnum< %s >::Enumerations\n", -				e->scoped(), e->scoped(), e->scoped()); -		fprintbf(cpp, "{\n\tModelPartForEnum< %s >::Enumerations e;\n", e->scoped()); +		size_t en = 0; +		for (const auto & ee : e->enumerators()) { +			fprintbf(cpp, "\tconst std::string estr%d_%d { \"%s\" };\n", components, en++, ee->name()); +		} +		fprintbf(cpp, "constexpr const EnumMapImpl< %s, %d > enumerations%d {{{\n", e->scoped(), +				e->enumerators().size(), components); +		en = 0;  		for (const auto & ee : e->enumerators()) { -			fprintbf(cpp, "\te.insert( { %s, \"%s\" } );\n", ee->scoped(), ee->name()); +			fprintbf(cpp, "\t {%s, \"%s\", &estr%d_%d},\n", ee->scoped(), ee->name(), components, en++);  		} -		fprintbf(cpp, "\treturn e;\n}());\n\n"); +		fprintbf(cpp, "\t}}};\n"); +		fprintbf(cpp, +				"\ttemplate<> constexpr const EnumMap< %s > & ModelPartForEnum< %s >::enumerations() { return " +				"enumerations%d; }\n", +				e->scoped(), e->scoped(), components);  		auto name = metaDataValue("slicer:root:", e->getMetaData());  		const Slice::TypePtr t = e;  | 
