Skip to content

Instantly share code, notes, and snippets.

@ifree
Last active December 18, 2016 18:18
Show Gist options
  • Select an option

  • Save ifree/f64c93f9e9b7fedf46e796a2b8cd06d9 to your computer and use it in GitHub Desktop.

Select an option

Save ifree/f64c93f9e9b7fedf46e796a2b8cd06d9 to your computer and use it in GitHub Desktop.
dumb pixel
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