diff options
author | Ben Wagner <bungeman@google.com> | 2017-10-18 11:30:56 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-10-18 19:43:18 +0000 |
commit | 7a0248f738dff64b95dc8e3f13e10984c3c27ebc (patch) | |
tree | 32868e17b911cdc0d6a4689ca0eca559bf2da217 /include | |
parent | 62cbb67a028de74c54940da0a63809c1881d5549 (diff) |
Compute inverse gamma table at compile time.
This introduces skstd::index_sequence and skstd::make_index_sequence so
that these can be used in C++11. These are mostly equivalent to their
std:: counterparts. This also introduces SkMakeArray<N, C>
which is constexpr and creates a std::array with N elements with each
element being initialized with the value of C(i) where i is the index of
the element.
These are then used to create inverse gamma table at compile time. This
avoids threading issues.
BUG=skia:7187
Change-Id: I61fb10a778898652e546d54c104a08d6e6bf88d3
Reviewed-on: https://skia-review.googlesource.com/61380
Commit-Queue: Ben Wagner <bungeman@google.com>
Reviewed-by: Mike Klein <mtklein@chromium.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/private/SkTLogic.h | 22 | ||||
-rw-r--r-- | include/private/SkTemplates.h | 11 |
2 files changed, 33 insertions, 0 deletions
diff --git a/include/private/SkTLogic.h b/include/private/SkTLogic.h index 6d6dc49535..cc76d7b618 100644 --- a/include/private/SkTLogic.h +++ b/include/private/SkTLogic.h @@ -14,6 +14,7 @@ #ifndef SkTLogic_DEFINED #define SkTLogic_DEFINED +#include <array> #include <stddef.h> #include <stdint.h> #include <type_traits> @@ -39,6 +40,8 @@ template <typename T> using add_cv_t = typename std::add_cv<T>::type; template <typename T> using add_pointer_t = typename std::add_pointer<T>::type; template <typename T> using add_lvalue_reference_t = typename std::add_lvalue_reference<T>::type; +template <typename T> using result_of_t = typename std::result_of<T>::type; + template <typename... T> using common_type_t = typename std::common_type<T...>::type; // Chromium currently requires gcc 4.8.2 or a recent clang compiler, but uses libstdc++4.6.4. @@ -64,6 +67,25 @@ template <typename T> using is_trivially_destructible = std::is_trivially_destru #endif template <typename T> using underlying_type_t = typename skstd::underlying_type<T>::type; + +template <std::size_t... Ints> struct index_sequence { + using type = index_sequence; + using value_type = size_t; + static constexpr std::size_t size() noexcept { return sizeof...(Ints); } +}; + +template <typename S1, typename S2> struct make_index_sequence_combine; +template <size_t... I1, size_t... I2> +struct make_index_sequence_combine<skstd::index_sequence<I1...>, skstd::index_sequence<I2...>> + : skstd::index_sequence<I1..., (sizeof...(I1)+I2)...> +{ }; + +template <size_t N> struct make_index_sequence + : make_index_sequence_combine<typename skstd::make_index_sequence< N/2>::type, + typename skstd::make_index_sequence<N - N/2>::type>{}; +template<> struct make_index_sequence<0> : skstd::index_sequence< >{}; +template<> struct make_index_sequence<1> : skstd::index_sequence<0>{}; + } // namespace skstd // The sknonstd namespace contains things we would like to be proposed and feel std-ish. diff --git a/include/private/SkTemplates.h b/include/private/SkTemplates.h index 5ebf13ac36..efe2ed306b 100644 --- a/include/private/SkTemplates.h +++ b/include/private/SkTemplates.h @@ -483,4 +483,15 @@ private: using SkAutoFree = std::unique_ptr<void, SkFunctionWrapper<void, void, sk_free>>; +template<typename C, std::size_t... Is> +constexpr auto SkMakeArrayFromIndexSequence(C c, skstd::index_sequence<Is...>) +-> std::array<skstd::result_of_t<C(std::size_t)>, sizeof...(Is)> { + return {{ c(Is)... }}; +} + +template<size_t N, typename C> constexpr auto SkMakeArray(C c) +-> std::array<skstd::result_of_t<C(std::size_t)>, N> { + return SkMakeArrayFromIndexSequence(c, skstd::make_index_sequence<N>{}); +} + #endif |