libcruft-util/colour.hpp

123 lines
2.9 KiB
C++
Raw Normal View History

2011-09-13 15:14:12 +10:00
/*
2018-08-04 15:14:06 +10:00
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
2011-09-13 15:14:12 +10:00
*
* Copyright 2010-2017 Danny Robson <danny@nerdcruft.net>
2011-09-13 15:14:12 +10:00
*/
#ifndef __UTIL_COLOUR_HPP
#define __UTIL_COLOUR_HPP
#include "coord.hpp"
2016-08-13 21:03:39 +10:00
#include "introspection.hpp"
2015-01-13 18:33:02 +11:00
#include <ostream>
#include <type_traits>
2011-09-13 15:14:12 +10:00
namespace util {
/// An abstract colour POD type componsed of S components of type T.
///
/// Not to be used directly, instead the use of derived types is required.
/// This exists purely to simplify generic colour code.
template <
size_t S,
typename T,
typename SelfT
>
struct colour : coord::base<S,T,SelfT> {
using coord::base<S,T,SelfT>::base;
2015-04-09 20:45:55 +10:00
template <typename U>
auto
cast (void) const
{
::util::revalue_t<SelfT,U> ret;
std::transform (std::begin (*this),
std::end (*this),
std::begin (ret),
renormalise<T,U>);
return ret;
}
2011-09-13 15:14:12 +10:00
};
template <typename T>
struct util::coord::store<1,T,srgba<1,T>> {
2018-03-06 18:13:39 +11:00
union {
struct { T r; };
T data[1];
};
};
template <typename T>
struct util::coord::store<2,T,srgba<2,T>> {
2018-03-06 18:13:39 +11:00
union {
struct { T r, g; };
T data[2];
};
};
template <typename T>
struct util::coord::store<3,T,srgba<3,T>> {
2018-03-06 18:13:39 +11:00
union {
struct { T r, g, b; };
T data[3];
};
};
template <typename T>
struct util::coord::store<4,T,srgba<4,T>> {
2018-03-06 18:13:39 +11:00
union {
struct { T r, g, b, a; };
T data[4];
};
};
2015-07-24 01:34:44 +10:00
template <size_t S, typename T> struct srgba : colour<S,T,srgba<S,T>> {
using colour<S,T,srgba<S,T>>::colour;
};
2015-04-09 21:50:42 +10:00
using srgba3f = srgba<3,float>;
using srgba4f = srgba<4,float>;
2015-01-13 18:33:02 +11:00
using srgba3u = srgba<3,uint8_t>;
using srgba4u = srgba<4,uint8_t>;
template <size_t S, typename T> struct hsva : colour<S,T,hsva<S,T>> {};
2016-04-02 13:37:58 +11:00
template <size_t S, typename T>
struct redim_type<
srgba<S,T>
> { template <size_t _S> using type = srgba<_S,T>; };
2016-08-13 21:03:39 +10:00
template <size_t S, typename T>
struct revalue_type<srgba<S,T>> {
template <typename _T>
using type = srgba<S,_T>;
2016-08-13 21:03:39 +10:00
};
template <typename> struct is_colour : public std::false_type {};
template <
size_t S,
typename T,
template <
size_t,
typename
> typename ColourT
> struct is_colour<ColourT<S,T>>
:std::conditional_t<
std::is_base_of_v<
colour<S,T,ColourT<S,T>>,
ColourT<S,T>
>,
std::true_type,
std::false_type
> {};
template <typename T>
constexpr auto is_colour_v = is_colour<T>::value;
2011-09-13 15:14:12 +10:00
}
#endif