summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mbgl/gl/attribute.hpp26
-rw-r--r--src/mbgl/gl/uniform.hpp8
-rw-r--r--src/mbgl/util/indexed_tuple.hpp47
3 files changed, 62 insertions, 19 deletions
diff --git a/src/mbgl/gl/attribute.hpp b/src/mbgl/gl/attribute.hpp
index a2b165fa21..47f93f31f9 100644
--- a/src/mbgl/gl/attribute.hpp
+++ b/src/mbgl/gl/attribute.hpp
@@ -2,11 +2,10 @@
#include <mbgl/gl/types.hpp>
#include <mbgl/util/ignore.hpp>
+#include <mbgl/util/indexed_tuple.hpp>
#include <cstddef>
#include <functional>
-#include <tuple>
-#include <utility>
namespace mbgl {
namespace gl {
@@ -143,27 +142,24 @@ void bindAttribute(AttributeLocation location,
template <class... As>
class Attributes {
public:
- using State = std::tuple<typename As::State...>;
+ using State = IndexedTuple<TypeList<As...>, TypeList<typename As::State...>>;
using Vertex = detail::Vertex<As...>;
+ template <class A>
+ static constexpr std::size_t Index = TypeIndex<A, As...>::value;
+
static State state(const ProgramID& id) {
return State { { attributeLocation(id, As::name) }... };
}
static std::function<void (std::size_t)> binder(const State& state) {
- return binder(state, std::index_sequence_for<As...>());
- }
-
-private:
- template <std::size_t... Is>
- static std::function<void (std::size_t)> binder(const State& state, std::index_sequence<Is...>) {
return [&state] (std::size_t vertexOffset) {
- ignore((bindAttribute(std::get<Is>(state).location,
- std::get<Is>(state).count,
- std::get<Is>(state).type,
- sizeof(Vertex),
- vertexOffset,
- Vertex::attributeOffsets[Is]), 0)...);
+ ignore({ (bindAttribute(state.template get<As>().location,
+ state.template get<As>().count,
+ state.template get<As>().type,
+ sizeof(Vertex),
+ vertexOffset,
+ Vertex::attributeOffsets[Index<As>]), 0)... });
};
}
};
diff --git a/src/mbgl/gl/uniform.hpp b/src/mbgl/gl/uniform.hpp
index df4de0c75a..0b303e9d6f 100644
--- a/src/mbgl/gl/uniform.hpp
+++ b/src/mbgl/gl/uniform.hpp
@@ -3,10 +3,10 @@
#include <mbgl/gl/types.hpp>
#include <mbgl/util/optional.hpp>
#include <mbgl/util/ignore.hpp>
+#include <mbgl/util/indexed_tuple.hpp>
#include <array>
#include <functional>
-#include <tuple>
namespace mbgl {
namespace gl {
@@ -63,8 +63,8 @@ UniformLocation uniformLocation(ProgramID, const char * name);
template <class... Us>
class Uniforms {
public:
- using State = std::tuple<typename Us::State...>;
- using Values = std::tuple<typename Us::Value...>;
+ using State = IndexedTuple<TypeList<Us...>, TypeList<typename Us::State...>>;
+ using Values = IndexedTuple<TypeList<Us...>, TypeList<typename Us::Value...>>;
static State state(const ProgramID& id) {
return State { { uniformLocation(id, Us::name) }... };
@@ -72,7 +72,7 @@ public:
static std::function<void ()> binder(State& state, Values&& values_) {
return [&state, values = std::move(values_)] () mutable {
- ignore((std::get<typename Us::State>(state) = std::get<typename Us::Value>(values), 0)...);
+ ignore({ (state.template get<Us>() = values.template get<Us>(), 0)... });
};
}
};
diff --git a/src/mbgl/util/indexed_tuple.hpp b/src/mbgl/util/indexed_tuple.hpp
new file mode 100644
index 0000000000..110e7dce12
--- /dev/null
+++ b/src/mbgl/util/indexed_tuple.hpp
@@ -0,0 +1,47 @@
+#pragma once
+
+#include <type_traits>
+#include <tuple>
+
+namespace mbgl {
+
+template <class T, class... Ts>
+struct TypeIndex;
+
+template <class T, class... Ts>
+struct TypeIndex<T, T, Ts...> : std::integral_constant<std::size_t, 0> {};
+
+template <class T, class U, class... Ts>
+struct TypeIndex<T, U, Ts...> : std::integral_constant<std::size_t, 1 + TypeIndex<T, Ts...>::value> {};
+
+template <class...> class TypeList {};
+
+template <class...> class IndexedTuple;
+
+// A tuple of Ts, where individual members can be accessed via `t.get<I>()` for I ∈ Is.
+//
+// See https://github.com/mapbox/cpp/blob/master/C%2B%2B%20Structural%20Metaprogramming.md
+// for motivation.
+//
+template <class... Is, class... Ts>
+class IndexedTuple<TypeList<Is...>, TypeList<Ts...>> : public std::tuple<Ts...> {
+public:
+ static_assert(sizeof...(Is) == sizeof...(Ts), "IndexedTuple size mismatch");
+
+ using std::tuple<Ts...>::tuple;
+
+ template <class I>
+ static constexpr std::size_t Index = TypeIndex<I, Is...>::value;
+
+ template <class I>
+ auto& get() {
+ return std::get<Index<I>>(*this);
+ }
+
+ template <class I>
+ const auto& get() const {
+ return std::get<Index<I>>(*this);
+ }
+};
+
+} // namespace mbgl