diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2016-11-03 12:44:36 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2016-11-08 08:09:29 -0800 |
commit | d1e2fe511ebf6d4aebbb08b2f0aba32e26c6edeb (patch) | |
tree | 6ca51ffe1a62f8e93af7fdff14b21e13e0e37b0f /src/mbgl | |
parent | 1db2ffbc1b69069eca39f786cacc45dbb02c3052 (diff) | |
download | qtlocation-mapboxgl-d1e2fe511ebf6d4aebbb08b2f0aba32e26c6edeb.tar.gz |
[core] Introduce and use IndexedTuple
Diffstat (limited to 'src/mbgl')
-rw-r--r-- | src/mbgl/gl/attribute.hpp | 26 | ||||
-rw-r--r-- | src/mbgl/gl/uniform.hpp | 8 | ||||
-rw-r--r-- | src/mbgl/util/indexed_tuple.hpp | 47 |
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 |