Shunsuke Shimizu лет назад: 10
Родитель
Сommit
be0f6e9323
5 измененных файлов с 43 добавлено и 20 удалено
  1. 1 1
      Makefile
  2. 1 1
      README.md
  3. 2 2
      lib/luwra/common.hpp
  4. 22 5
      lib/luwra/types.hpp
  5. 17 11
      lib/luwra/usertypes.hpp

+ 1 - 1
Makefile

@@ -23,7 +23,7 @@ LUA_LIBNAME     = lua
 
 # Compiler
 CXX             ?= clang++
-USECXXFLAGS     += $(CXXFLAGS) -std=c++14 -O0 -g -DDEBUG -fmessage-length=0 -Wall -Wextra \
+USECXXFLAGS     += $(CXXFLAGS) -std=c++11 -O0 -g -DDEBUG -fmessage-length=0 -Wall -Wextra \
                    -pedantic -D_GLIBCXX_USE_C99 -Ilib -I$(LUA_INCDIR) -Ideps/catch/include
 USELDFLAGS      += $(LDFLAGS) -L$(LUA_LIBDIR)
 USELDLIBS       += $(LDLIBS) -lm -l$(LUA_LIBNAME) -ldl

+ 1 - 1
README.md

@@ -140,7 +140,7 @@ point:x(4.2)
 ```
 
 ## Requirements
-You need a C++14-compliant compiler and at least Lua 5.1 to get this library to work. I recommend
+You need a C++11-compliant compiler and at least Lua 5.1 to get this library to work. I recommend
 using Lua 5.3 or later, to avoid the messy `lua_Integer` situation. LuaJIT 2.0 seems to work, apart
 from user types, which fail for yet unknown reasons.
 

+ 2 - 2
lib/luwra/common.hpp

@@ -8,8 +8,8 @@
 #define LUWRA_COMMON_H_
 
 // Check C++ version
-#if !defined(__cplusplus) || __cplusplus < 201402L
-	#error You need a C++14 compliant compiler
+#if !defined(__cplusplus) || __cplusplus < 201103L
+	#error You need a C++11 compliant compiler
 #endif
 
 extern "C" {

+ 22 - 5
lib/luwra/types.hpp

@@ -337,11 +337,28 @@ struct Value<Arbitrary> {
 };
 
 namespace internal {
+	// C++11 implementation of C++14's `index_sequence` and `make_index_sequence`.
+	template<size_t... Is>
+	struct index_sequence {};
+
+	template<size_t I, size_t... Is>
+	struct make_index_sequence_impl {
+		typedef typename make_index_sequence_impl<I - 1, I - 1, Is...>::type type;
+	};
+
+	template<size_t... Is>
+	struct make_index_sequence_impl<0, Is...> {
+		typedef index_sequence<Is...> type;
+	};
+
+	template<size_t I>
+	using make_index_sequence = typename make_index_sequence_impl<I>::type;
+
 	template <typename>
 	struct StackPusher;
 
 	template <size_t I>
-	struct StackPusher<std::index_sequence<I>> {
+	struct StackPusher<index_sequence<I>> {
 		template <typename... T> static inline
 		size_t push(State* state, const std::tuple<T...>& package) {
 			using R = typename std::tuple_element<I, std::tuple<T...>>::type;
@@ -350,12 +367,12 @@ namespace internal {
 	};
 
 	template <size_t I, size_t... Is>
-	struct StackPusher<std::index_sequence<I, Is...>> {
+	struct StackPusher<index_sequence<I, Is...>> {
 		template <typename... T> static inline
 		size_t push(State* state, const std::tuple<T...>& package) {
 			return
-				StackPusher<std::index_sequence<I>>::push(state, package)
-				+ StackPusher<std::index_sequence<Is...>>::push(state, package);
+				StackPusher<index_sequence<I>>::push(state, package)
+				+ StackPusher<index_sequence<Is...>>::push(state, package);
 		}
 	};
 }
@@ -367,7 +384,7 @@ template <typename... A>
 struct Value<std::tuple<A...>> {
 	static inline
 	size_t push(State* state, const std::tuple<A...>& value) {
-		return internal::StackPusher<std::make_index_sequence<sizeof...(A)>>::push(state, value);
+		return internal::StackPusher<internal::make_index_sequence<sizeof...(A)>>::push(state, value);
 	}
 };
 

+ 17 - 11
lib/luwra/usertypes.hpp

@@ -17,23 +17,29 @@
 LUWRA_NS_BEGIN
 
 namespace internal {
-	using UserTypeID = const void*;
+	using UserTypeID = int;
 
 	template <typename T>
-	using StripUserType = std::remove_cv_t<T>;
+	using StripUserType = typename std::remove_cv<T>::type;
 
 	/**
 	 * User type identifier
 	 */
-	template <typename T> extern
-	const UserTypeID user_type_id = (void*) INTPTR_MAX;
+	// In C++14 a template variable can be used instead of following.
+	template <typename T>
+	struct UserTypeIDWrapper {
+		static constexpr UserTypeID value = INT_MAX;
+	};
+	template <typename T>
+	constexpr UserTypeID UserTypeIDWrapper<T>::value;
 
 	/**
 	 * Registry name for a metatable which is associated with a user type
 	 */
-	template <typename T> extern
-	const std::string user_type_reg_name =
-		"UD#" + std::to_string(uintptr_t(&user_type_id<StripUserType<T>>));
+	template <typename T>
+	std::string user_type_reg_name() {
+		return "UD#" + std::to_string(uintptr_t(&UserTypeIDWrapper<StripUserType<T>>::value));
+	}
 
 	/**
 	 * Register a new metatable for a user type T.
@@ -41,7 +47,7 @@ namespace internal {
 	template <typename U> static inline
 	void new_user_type_metatable(State* state) {
 		using T = StripUserType<U>;
-		luaL_newmetatable(state, user_type_reg_name<T>.c_str());
+		luaL_newmetatable(state, user_type_reg_name<T>().c_str());
 	}
 
 	/**
@@ -50,7 +56,7 @@ namespace internal {
 	template <typename U> static inline
 	StripUserType<U>* check_user_type(State* state, int index) {
 		using T = StripUserType<U>;
-		return static_cast<T*>(luaL_checkudata(state, index, user_type_reg_name<T>.c_str()));
+		return static_cast<T*>(luaL_checkudata(state, index, user_type_reg_name<T>().c_str()));
 	}
 
 	/**
@@ -60,7 +66,7 @@ namespace internal {
 	void apply_user_type_meta_table(State* state) {
 		using T = StripUserType<U>;
 
-		luaL_getmetatable(state, user_type_reg_name<T>.c_str());
+		luaL_getmetatable(state, user_type_reg_name<T>().c_str());
 		lua_setmetatable(state, -2);
 	}
 
@@ -98,7 +104,7 @@ namespace internal {
 
 		return push(
 			state,
-			internal::user_type_reg_name<T>
+			internal::user_type_reg_name<T>()
 				+ "@"
 				+ std::to_string(uintptr_t(Value<T*>::read(state, 1)))
 		);