From 7a0248f738dff64b95dc8e3f13e10984c3c27ebc Mon Sep 17 00:00:00 2001 From: Ben Wagner Date: Wed, 18 Oct 2017 11:30:56 -0400 Subject: 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 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 Reviewed-by: Mike Klein --- include/private/SkTLogic.h | 22 ++++++++++++++++++++++ include/private/SkTemplates.h | 11 +++++++++++ 2 files changed, 33 insertions(+) (limited to 'include/private') 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 #include #include #include @@ -39,6 +40,8 @@ template using add_cv_t = typename std::add_cv::type; template using add_pointer_t = typename std::add_pointer::type; template using add_lvalue_reference_t = typename std::add_lvalue_reference::type; +template using result_of_t = typename std::result_of::type; + template using common_type_t = typename std::common_type::type; // Chromium currently requires gcc 4.8.2 or a recent clang compiler, but uses libstdc++4.6.4. @@ -64,6 +67,25 @@ template using is_trivially_destructible = std::is_trivially_destru #endif template using underlying_type_t = typename skstd::underlying_type::type; + +template struct index_sequence { + using type = index_sequence; + using value_type = size_t; + static constexpr std::size_t size() noexcept { return sizeof...(Ints); } +}; + +template struct make_index_sequence_combine; +template +struct make_index_sequence_combine, skstd::index_sequence> + : skstd::index_sequence +{ }; + +template struct make_index_sequence + : make_index_sequence_combine::type, + typename skstd::make_index_sequence::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>; +template +constexpr auto SkMakeArrayFromIndexSequence(C c, skstd::index_sequence) +-> std::array, sizeof...(Is)> { + return {{ c(Is)... }}; +} + +template constexpr auto SkMakeArray(C c) +-> std::array, N> { + return SkMakeArrayFromIndexSequence(c, skstd::make_index_sequence{}); +} + #endif -- cgit v1.2.3