Last active
December 18, 2016 18:18
-
-
Save ifree/f64c93f9e9b7fedf46e796a2b8cd06d9 to your computer and use it in GitHub Desktop.
dumb pixel
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| template<size_t... ComponentSizes> | |
| class Pixel { | |
| template<size_t... I> | |
| static auto make_components(std::index_sequence<I...>) | |
| { | |
| auto constexpr sizes = std::make_tuple(ComponentSizes...); | |
| //size = offset + sizeI | |
| return std::make_tuple(Bitfield<storage_type, partial_sum<I>::value(sizes), std::get<I>(sizes)>{}...); | |
| } | |
| static auto make_components() | |
| { | |
| return make_components(std::make_index_sequence<sizeof...(ComponentSizes)>()); | |
| } | |
| public: | |
| static constexpr size_t total_size = sum_of<ComponentSizes...>::value; | |
| static constexpr size_t num_components = sizeof...(ComponentSizes); | |
| using storage_type = //detect pixel storage size by size of total components | |
| std::conditional_t<total_size == 0, void, | |
| std::conditional_t<total_size <= 8, uint8_t, | |
| std::conditional_t<total_size <= 16, uint16_t, | |
| std::conditional_t<total_size <= 32, uint32_t, | |
| std::conditional_t<total_size <= 64, uint64_t, | |
| void>>>>>; | |
| using component_storage_type = decltype(make_components()); | |
| Pixel() | |
| : components_{} | |
| {} | |
| //set whole pixel value, eg: packed rgba | |
| Pixel(storage_type pixel) | |
| { | |
| set_value(pixel); | |
| } | |
| //set pixel component separately, eg Pixel pixel{r, g, b, a} | |
| template<size_t N> | |
| Pixel(const storage_type(&comps)[N]) : components_{} | |
| { | |
| static_assert(N == num_components, "invalid size of components"); | |
| set_recursive<N - 1>(comps); | |
| } | |
| //get packed pixel value | |
| storage_type get_value() const | |
| { | |
| return get_value_unpacked(std::make_index_sequence<num_components>()); | |
| } | |
| //set packed pixel value | |
| void set_value(storage_type pixel) | |
| { | |
| set_value_recursive<num_components - 1>(pixel); | |
| } | |
| //get pixel component value | |
| template<size_t index> | |
| storage_type get() const | |
| { | |
| return std::get<index>(components_); | |
| } | |
| //set pixel component value | |
| template<size_t index> | |
| void set(storage_type val) | |
| { | |
| std::get<index>(components_) = val; | |
| } | |
| private: | |
| template<size_t... I> | |
| storage_type get_value_unpacked(std::index_sequence<I...>) const | |
| { | |
| storage_type ret = 0; | |
| unpack((ret |= std::get<I>(components_).get_value())...); | |
| return ret; | |
| } | |
| template<size_t N> | |
| void set_recursive(const storage_type *comps) | |
| { | |
| static_assert(N >= 0, "invalid tuple index"); | |
| set<N>(comps[N]); | |
| set_recursive<N - 1>(comps); | |
| } | |
| template<> | |
| void set_recursive<0>(const storage_type *comps) | |
| { | |
| set<0>(comps[0]); | |
| } | |
| template<size_t N> | |
| void set_value_recursive(storage_type comp) | |
| { | |
| static_assert(N >= 0, "invalid tuple index"); | |
| std::get<N>(components_).set_value(comp); | |
| set_value_recursive<N - 1>(comp); | |
| } | |
| template<> | |
| void set_value_recursive<0>(storage_type comp) | |
| { | |
| std::get<0>(components_).set_value(comp); | |
| } | |
| private: | |
| component_storage_type components_; | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment