From d3f434b523b4a6b41b1024fc993a86a0cd6f3683 Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Wed, 22 Nov 2017 17:03:00 +1100 Subject: [PATCH] coord: make template parameters more flexible The coordinate system was unable to support types that prohibited redim or retype operations. Additionally, the `tags' type used for providing named data parameters was unwiedly. We remove much of the dependance on template template parameters in the defined operations and instead define these in terms of a template specialisation of is_coord. The tag types were replaced with direct specialisation of the `store' struct by the primary type, and passing this type through use of the CRTP. --- CMakeLists.txt | 2 +- colour.cpp | 450 -------------------------- colour.hpp | 138 ++++---- colour.ipp | 12 - coord/base.hpp | 83 +++-- coord/fwd.hpp | 15 +- coord/init.hpp | 34 +- coord/iostream.hpp | 4 +- coord/names.hpp | 42 --- coord/ops.hpp | 750 +++++++++++++++++++++++--------------------- coord/store.hpp | 230 +++++--------- coord/traits.hpp | 170 ++++++++++ extent.cpp | 6 +- extent.hpp | 32 +- geom/aabb.cpp | 86 ----- geom/aabb.hpp | 14 +- geom/plane.cpp | 3 +- geom/plane.hpp | 7 +- hash/bsdsum.cpp | 5 +- maths.hpp | 6 +- matrix.cpp | 115 +++---- matrix.hpp | 172 +++++++--- matrix.ipp | 104 +++--- matrix2.cpp | 12 +- matrix3.cpp | 26 +- matrix4.cpp | 135 ++++++-- point.hpp | 4 +- quaternion.hpp | 10 +- random.hpp | 40 ++- test/affine.cpp | 48 +-- test/colour.cpp | 76 +---- test/geom/aabb.cpp | 37 --- test/point.cpp | 5 + test/quaternion.cpp | 4 +- test/string.cpp | 11 +- vector.hpp | 4 +- view.cpp | 2 +- 37 files changed, 1296 insertions(+), 1598 deletions(-) delete mode 100644 coord/names.hpp create mode 100644 coord/traits.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 14a94bb7..08633272 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -180,9 +180,9 @@ list ( coord.hpp coord/init.hpp coord/iostream.hpp - coord/names.hpp coord/ops.hpp coord/store.hpp + coord/traits.hpp crypto/arc4.cpp crypto/arc4.hpp crypto/ice.cpp diff --git a/colour.cpp b/colour.cpp index a38567fb..1525606e 100644 --- a/colour.cpp +++ b/colour.cpp @@ -15,453 +15,3 @@ */ #include "colour.hpp" - -#include "ascii.hpp" -#include "debug.hpp" -#include "log.hpp" -#include "range.hpp" - -#include -#include - -/////////////////////////////////////////////////////////////////////////////// -using util::colour; -using util::colour3f; -using util::colour4f; - - -/////////////////////////////////////////////////////////////////////////////// -template -colour -colour::parse_html (const char *fmt) -{ - // ensure the format is the correct length - auto len = strlen (fmt); - - switch (len) { - case 1 + 2 * S: - if (*fmt != '#') - throw std::invalid_argument ("missing leading hash"); - ++fmt; - break; - - case 2 * S: - break; - - default: - throw std::invalid_argument ("format is the wrong length"); - } - - // parse the octets - util::colour res; - for (size_t i = 0; i < res.size (); ++i) { - auto a = util::ascii::from_hex (fmt[i*2+0]); - auto b = util::ascii::from_hex (fmt[i*2+1]); - - res[i] = (a << 4u) | b; - } - - return res.template cast (); -} - - -/////////////////////////////////////////////////////////////////////////////// -static const std::map> -HTML_COLOURS { { - { "white", { 0xff, 0xff, 0xff, 0xff } }, - { "silver", { 0xc0, 0xc0, 0xc0, 0xff } }, - { "gray", { 0x80, 0x80, 0x80, 0xff } }, - { "black", { 0x00, 0x00, 0x00, 0xff } }, - { "red", { 0xff, 0x00, 0x00, 0xff } }, - { "maroon", { 0x80, 0x00, 0x00, 0xff } }, - { "yellow", { 0xff, 0xff, 0x00, 0xff } }, - { "olive", { 0x80, 0x80, 0x00, 0xff } }, - { "lime", { 0x00, 0xff, 0x00, 0xff } }, - { "green", { 0x00, 0x80, 0x00, 0xff } }, - { "aqua", { 0x00, 0xff, 0xff, 0xff } }, - { "teal", { 0x00, 0x80, 0x80, 0xff } }, - { "blue", { 0x00, 0x00, 0xff, 0xff } }, - { "navy", { 0x00, 0x00, 0x80, 0xff } }, - { "fuchsia", { 0xff, 0x00, 0xff, 0xff } }, - { "purple", { 0x80, 0x00, 0x80, 0xff } }, -} }; - - -//----------------------------------------------------------------------------- -static const std::map> X11_COLOURS -{ - /* pink */ - { "pink", { 0xff, 0xc0, 0xcb, 0xff } }, - { "lightpink", { 0xff, 0xb6, 0xc1, 0xff } }, - { "hotpink", { 0xff, 0x69, 0xb4, 0xff } }, - { "deeppink", { 0xff, 0x14, 0x93, 0xff } }, - { "palevioletred", { 0xdb, 0x70, 0x93, 0xff } }, - { "mediumvioletred", { 0xc7, 0x15, 0x85, 0xff } }, - - /* red */ - { "lightsalmon", { 0xff, 0xa0, 0x7a, 0xff } }, - { "salmon", { 0xfa, 0x80, 0x72, 0xff } }, - { "darksalmon", { 0xe9, 0x96, 0x7a, 0xff } }, - { "lightcoral", { 0xf0, 0x80, 0x80, 0xff } }, - { "indianred", { 0xcd, 0x5c, 0x5c, 0xff } }, - { "crimson", { 0xdc, 0x14, 0x3c, 0xff } }, - { "firebrick", { 0xb2, 0x22, 0x22, 0xff } }, - { "darkred", { 0x8b, 0x00, 0x00, 0xff } }, - { "red", { 0xff, 0x00, 0x00, 0xff } }, - - /* orange */ - { "orangered", { 0xff, 0x45, 0x00, 0xff } }, - { "tomato", { 0xff, 0x63, 0x47, 0xff } }, - { "coral", { 0xff, 0x7f, 0x50, 0xff } }, - { "darkorange", { 0xff, 0x8c, 0x00, 0xff } }, - { "orange", { 0xff, 0xa5, 0x00, 0xff } }, - - /* yellow */ - { "yellow", { 0xff, 0xff, 0x00, 0xff } }, - { "lightyellow", { 0xff, 0xff, 0xe0, 0xff } }, - { "lemonchiffon", { 0xff, 0xfa, 0xcd, 0xff } }, - { "lightgoldenrodyellow", { 0xfa, 0xfa, 0xd2, 0xff } }, - { "papayawhip", { 0xff, 0xef, 0xd5, 0xff } }, - { "moccasin", { 0xff, 0xe4, 0xb5, 0xff } }, - { "peachpuff", { 0xff, 0xda, 0xb9, 0xff } }, - { "palegoldenrod", { 0xee, 0xe8, 0xaa, 0xff } }, - { "khaki", { 0xf0, 0xe6, 0x8c, 0xff } }, - { "darkkhaki", { 0xbd, 0xb7, 0x6b, 0xff } }, - { "gold", { 0xff, 0xd7, 0x00, 0xff } }, - - /* brown */ - { "cornsilk", { 0xff, 0xf8, 0xdc, 0xff } }, - { "blanchedalmond", { 0xff, 0xeb, 0xcd, 0xff } }, - { "bisque", { 0xff, 0xe4, 0xc4, 0xff } }, - { "navajowhite", { 0xff, 0xde, 0xad, 0xff } }, - { "wheat", { 0xf5, 0xde, 0xb3, 0xff } }, - { "burlywood", { 0xde, 0xb8, 0x87, 0xff } }, - { "tan", { 0xd2, 0xb4, 0x8c, 0xff } }, - { "rosybrown", { 0xbc, 0x8f, 0x8f, 0xff } }, - { "sandybrown", { 0xf4, 0xa4, 0x60, 0xff } }, - { "goldenrod", { 0xda, 0xa5, 0x20, 0xff } }, - { "darkgoldenrod", { 0xb8, 0x86, 0x0b, 0xff } }, - { "peru", { 0xcd, 0x85, 0x3f, 0xff } }, - { "chocolate", { 0xd2, 0x69, 0x1e, 0xff } }, - { "saddlebrown", { 0x8b, 0x45, 0x13, 0xff } }, - { "sienna", { 0xa0, 0x52, 0x2d, 0xff } }, - { "brown", { 0xa5, 0x2a, 0x2a, 0xff } }, - { "maroon", { 0x80, 0x00, 0x00, 0xff } }, - - /* green */ - { "darkolivegreen", { 0x55, 0x6b, 0x2f, 0xff } }, - { "olive", { 0x80, 0x80, 0x00, 0xff } }, - { "olivedrab", { 0x6b, 0x8e, 0x23, 0xff } }, - { "yellowgreen", { 0x9a, 0xcd, 0x32, 0xff } }, - { "limegreen", { 0x32, 0xcd, 0x32, 0xff } }, - { "lime", { 0x00, 0xff, 0x00, 0xff } }, - { "lawngreen", { 0x7c, 0xfc, 0x00, 0xff } }, - { "chartreuse", { 0x7f, 0xff, 0x00, 0xff } }, - { "greenyellow", { 0xad, 0xff, 0x2f, 0xff } }, - { "springgreen", { 0x00, 0xff, 0x7f, 0xff } }, - { "mediumspringgreen", { 0x00, 0xfa, 0x9a, 0xff } }, - { "lightgreen", { 0x90, 0xee, 0x90, 0xff } }, - { "palegreen", { 0x98, 0xfb, 0x98, 0xff } }, - { "darkseagreen", { 0x8f, 0xbc, 0x8f, 0xff } }, - { "mediumseagreen", { 0x3c, 0xb3, 0x71, 0xff } }, - { "seagreen", { 0x2e, 0x8b, 0x57, 0xff } }, - { "forestgreen", { 0x22, 0x8b, 0x22, 0xff } }, - { "green", { 0x00, 0x80, 0x00, 0xff } }, - { "darkgreen", { 0x00, 0x64, 0x00, 0xff } }, - - /* cyan */ - { "mediumaquamarine", { 0x66, 0xcd, 0xaa, 0xff } }, - { "aqua", { 0x00, 0xff, 0xff, 0xff } }, - { "cyan", { 0x00, 0xff, 0xff, 0xff } }, - { "lightcyan", { 0xe0, 0xff, 0xff, 0xff } }, - { "paleturquoise", { 0xaf, 0xee, 0xee, 0xff } }, - { "aquamarine", { 0x7f, 0xff, 0xd4, 0xff } }, - { "turquoise", { 0x40, 0xe0, 0xd0, 0xff } }, - { "mediumturquoise", { 0x48, 0xd1, 0xcc, 0xff } }, - { "darkturquoise", { 0x00, 0xce, 0xd1, 0xff } }, - { "lightseagreen", { 0x20, 0xb2, 0xaa, 0xff } }, - { "cadetblue", { 0x5f, 0x9e, 0xa0, 0xff } }, - { "darkcyan", { 0x00, 0x8b, 0x8b, 0xff } }, - { "teal", { 0x00, 0x80, 0x80, 0xff } }, - - /* blue */ - { "lightsteelblue", { 0xb0, 0xc4, 0xde, 0xff } }, - { "powderblue", { 0xb0, 0xe0, 0xe6, 0xff } }, - { "lightblue", { 0xad, 0xd8, 0xe6, 0xff } }, - { "skyblue", { 0x87, 0xce, 0xeb, 0xff } }, - { "lightskyblue", { 0x87, 0xce, 0xfa, 0xff } }, - { "deepskyblue", { 0x00, 0xbf, 0xff, 0xff } }, - { "dodgerblue", { 0x1e, 0x90, 0xff, 0xff } }, - { "cornflowerblue", { 0x64, 0x95, 0xed, 0xff } }, - { "steelblue", { 0x46, 0x82, 0xb4, 0xff } }, - { "royalblue", { 0x41, 0x69, 0xe1, 0xff } }, - { "blue", { 0x00, 0x00, 0xff, 0xff } }, - { "mediumblue", { 0x00, 0x00, 0xcd, 0xff } }, - { "darkblue", { 0x00, 0x00, 0x8b, 0xff } }, - { "navy", { 0x00, 0x00, 0x80, 0xff } }, - { "midnightblue", { 0x19, 0x19, 0x70, 0xff } }, - - /* purple */ - { "lavender", { 0xe6, 0xe6, 0xfa, 0xff } }, - { "thistle", { 0xd8, 0xbf, 0xd8, 0xff } }, - { "plum", { 0xdd, 0xa0, 0xdd, 0xff } }, - { "violet", { 0xee, 0x82, 0xee, 0xff } }, - { "orchid", { 0xda, 0x70, 0xd6, 0xff } }, - { "fuchsia", { 0xff, 0x00, 0xff, 0xff } }, - { "magenta", { 0xff, 0x00, 0xff, 0xff } }, - { "mediumorchid", { 0xba, 0x55, 0xd3, 0xff } }, - { "mediumpurple", { 0x93, 0x70, 0xdb, 0xff } }, - { "blueviolet", { 0x8a, 0x2b, 0xe2, 0xff } }, - { "darkviolet", { 0x94, 0x00, 0xd3, 0xff } }, - { "darkorchid", { 0x99, 0x32, 0xcc, 0xff } }, - { "darkmagenta", { 0x8b, 0x00, 0x8b, 0xff } }, - { "purple", { 0x80, 0x00, 0x80, 0xff } }, - { "indigo", { 0x4b, 0x00, 0x82, 0xff } }, - { "darkslateblue", { 0x48, 0x3d, 0x8b, 0xff } }, - { "rebeccapurple", { 0x66, 0x33, 0x99, 0xff } }, - { "slateblue", { 0x6a, 0x5a, 0xcd, 0xff } }, - { "mediumslateblue", { 0x7b, 0x68, 0xee, 0xff } }, - - /* white */ - { "white", { 0xff, 0xff, 0xff, 0xff } }, - { "snow", { 0xff, 0xfa, 0xfa, 0xff } }, - { "honeydew", { 0xf0, 0xff, 0xf0, 0xff } }, - { "mintcream", { 0xf5, 0xff, 0xfa, 0xff } }, - { "azure", { 0xf0, 0xff, 0xff, 0xff } }, - { "aliceblue", { 0xf0, 0xf8, 0xff, 0xff } }, - { "ghostwhite", { 0xf8, 0xf8, 0xff, 0xff } }, - { "whitesmoke", { 0xf5, 0xf5, 0xf5, 0xff } }, - { "seashell", { 0xff, 0xf5, 0xee, 0xff } }, - { "beige", { 0xf5, 0xf5, 0xdc, 0xff } }, - { "oldlace", { 0xfd, 0xf5, 0xe6, 0xff } }, - { "floralwhite", { 0xff, 0xfa, 0xf0, 0xff } }, - { "ivory", { 0xff, 0xff, 0xf0, 0xff } }, - { "antiquewhite", { 0xfa, 0xeb, 0xd7, 0xff } }, - { "linen", { 0xfa, 0xf0, 0xe6, 0xff } }, - { "lavenderblush", { 0xff, 0xf0, 0xf5, 0xff } }, - { "mistyrose", { 0xff, 0xe4, 0xe1, 0xff } }, - - /* grey/black */ - { "gainsboro", { 0xdc, 0xdc, 0xdc, 0xff } }, - { "lightgrey", { 0xd3, 0xd3, 0xd3, 0xff } }, - { "silver", { 0xc0, 0xc0, 0xc0, 0xff } }, - { "darkgray", { 0xa9, 0xa9, 0xa9, 0xff } }, - { "gray", { 0x80, 0x80, 0x80, 0xff } }, - { "dimgray", { 0x69, 0x69, 0x69, 0xff } }, - { "lightslategray", { 0x77, 0x88, 0x99, 0xff } }, - { "slategray", { 0x70, 0x80, 0x90, 0xff } }, - { "darkslategray", { 0x2f, 0x4f, 0x4f, 0xff } }, - { "black", { 0x00, 0x00, 0x00, 0xff } }, -}; - - -//----------------------------------------------------------------------------- -template -static colour -lookup_colour (const std::string &name, - const std::map> &map) -{ - std::string lower (name); - std::transform (lower.begin (), lower.end (), lower.begin (), tolower); - - auto pos = map.find (lower); - if (pos == map.end ()) - throw std::out_of_range (name); - - static_assert (S <= 4, "cannot invent additional data"); - return pos->second.template redim ().template cast (); -} - - -//----------------------------------------------------------------------------- -template -colour -colour::from_html (const std::string &name) -{ - return lookup_colour (name, HTML_COLOURS); -} - - -//----------------------------------------------------------------------------- -template -colour -colour::from_x11 (const std::string &name) -{ - return lookup_colour (name, X11_COLOURS); -} - - -/////////////////////////////////////////////////////////////////////////////// -colour3f -util::rgb_to_hsv (colour3f rgb) -{ - // Calculate chroma - auto M = max (rgb); - auto m = min (rgb); - auto C = M - m; - - // Undefined for zero chroma - if (almost_zero (C)) - return { -1.f, 0.f, M }; - - // Calculate hue - float H = exactly_equal (rgb.r, M) ? (rgb.g - rgb.b) : - exactly_equal (rgb.g, M) ? 2 + (rgb.b - rgb.r) : - exactly_equal (rgb.b, M) ? 4 + (rgb.r - rgb.g) : - 0 ; - - H /= C; - H *= 60; - - if (H < 0) - H += 360; - - // Calculate value - auto V = M; - - // Calculate saturation - auto S = almost_zero (V) ? 0.f : C / V; - - return { H, S, V }; -} - - -//----------------------------------------------------------------------------- -colour3f -util::hsv_to_rgb (colour3f hsv) -{ - CHECK_GE (hsv.h, 0); - CHECK_LT (hsv.h, 360); - CHECK_GE (hsv.s, 0); - CHECK_LE (hsv.s, 1); - CHECK_GE (hsv.v, 0); - CHECK_LE (hsv.v, 1); - - float C = hsv.v * hsv.s; - float H = hsv.h / 60; - float X = C * (1 - std::abs (std::fmod (H, 2.f) - 1)); - - // monochromatic'ish - if (almost_zero (hsv.s)) - return colour3f { hsv.v }; - - colour3f rgb; - - unsigned hex = (unsigned)H; - switch (hex) { - case 0: rgb = { C, X, 0 }; break; - case 1: rgb = { X, C, 0 }; break; - case 2: rgb = { 0, C, X }; break; - case 3: rgb = { 0, X, C }; break; - case 4: rgb = { X, 0, C }; break; - case 5: rgb = { C, 0, X }; break; - } - - auto m = hsv.v - C; - - return rgb + m; -} - - -///---------------------------------------------------------------------------- -/// Extract a colour object from a JSON node. -#include "json/tree.hpp" - -namespace json::tree { - template <> - util::colour4f - io::deserialise (const node &root) { - return { - root[0].as (), - root[1].as (), - root[2].as (), - root[3].as (), - }; - } -} - - -/////////////////////////////////////////////////////////////////////////////// -template -std::ostream& -util::operator<< (std::ostream &os, util::colour c) { - os << "colour("; - for (size_t i = 0; i < S - 1; ++i) - os << +c[i] << ", "; - os << +c[S-1] << ")"; - return os; -} - - -//----------------------------------------------------------------------------- -template -std::istream& -util::operator>> (std::istream &is, util::colour &c) -{ - std::array< - std::conditional_t< - sizeof(T) == 1, - uint16_t, - T - >,S - > v; - - static_assert (S > 0, "current implementation requires strictly positive components"); - char comma; - - for (size_t i = 0; i < S - 1; ++i) { - is >> v[i] >> comma; - - if (comma != ',' || is.eof ()) { - is.setstate (std::ios_base::failbit); - return is; - } - } - - is >> v[S-1]; - - if (!std::is_same::value) { - if (std::any_of (std::cbegin (v), - std::cend (v), - [] (auto i) { - return i > std::numeric_limits::max (); - })) { - is.setstate (std::ios_base::failbit); - return is; - } - } - - std::copy (std::cbegin (v), - std::cend (v), - std::begin (c)); - - return is; -} - -template std::istream& util::operator>> (std::istream&, util::colour<3,uint8_t>&); - -/////////////////////////////////////////////////////////////////////////////// -#define INSTANTIATE_S_T(S,T) \ -template \ -struct util::colour; \ - \ -template \ -std::ostream& \ -util::operator<< (std::ostream&, util::colour); \ - \ -template \ -const char* \ -util::to_string> (void); - - -//----------------------------------------------------------------------------- -#define INSTANTIATE_S(S) \ -INSTANTIATE_S_T(S,uint8_t) \ -INSTANTIATE_S_T(S,float) \ -INSTANTIATE_S_T(S,double) - - -//----------------------------------------------------------------------------- -INSTANTIATE_S(1) -INSTANTIATE_S(3) -INSTANTIATE_S(4) diff --git a/colour.hpp b/colour.hpp index 7bed5b15..7e49056d 100644 --- a/colour.hpp +++ b/colour.hpp @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * Copyright 2010-2015 Danny Robson + * Copyright 2010-2017 Danny Robson */ #ifndef __UTIL_COLOUR_HPP @@ -21,68 +21,94 @@ #include "introspection.hpp" #include +#include namespace util { - /// An RGBA colour POD type. - template - struct colour : public coord::base { - using coord::base::base; - using base_t = coord::base; + /// 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 { + using coord::base::base; - // overloaded cast operator which assumes values are unit normalised template - colour - cast (void) const; - - /// parse colours specified as "#AABBCCDD". - /// - /// * the leading hash is optional. - /// * all components must be 2 hex digits. - static colour parse_html (const char*); - static colour parse_html (const std::string&); - - /// look up the name of a colour from those specified in - /// html/x11/etc specifications. - static colour from_html (const std::string &name); - static colour from_x11 (const std::string &name); - - /// look up all the specifications and returns the colour from one - /// that matches. the search order is unspecified, so if you want a - /// known colour then try them first yourself. - static colour from_string (const std::string &name); + auto + cast (void) const + { + ::util::revalue_t ret; + std::transform (std::begin (*this), + std::end (*this), + std::begin (ret), + renormalise); + return ret; + } }; - // Convenience types - template using colour1 = colour<1,T>; - template using colour3 = colour<3,T>; - template using colour4 = colour<4,T>; - - typedef colour1 colour1u; - typedef colour3 colour3u; - typedef colour4 colour4u; - - typedef colour1 colour1f; - typedef colour3 colour3f; - typedef colour4 colour4f; - - // RGB/HSV conversions - colour3f rgb_to_hsv (colour3f); - colour3f hsv_to_rgb (colour3f); - - // ostream/istream operators - template - std::ostream& - operator<< (std::ostream&, util::colour); - - template - std::istream& - operator>> (std::istream&, util::colour&); - - // type name introspection specialisation - template - struct type_name> { - static constexpr const char value[] = "colour"; + template + struct util::coord::store<1,T,srgba<1,T>> { + union { struct { T r; }; T data[1]; }; }; + template + struct util::coord::store<2,T,srgba<2,T>> { + union { struct { T r, g; }; T data[2]; }; + }; + template + struct util::coord::store<3,T,srgba<3,T>> { + union { struct { T r, g, b; }; T data[3]; }; + }; + + template + struct util::coord::store<4,T,srgba<4,T>> { + union { struct { T r, g, b, a; }; T data[4]; }; + }; + + template struct srgba : colour> { + using colour>::colour; + }; + + using srgba3f = srgba<3,float>; + using srgba4f = srgba<4,float>; + + template struct hsva : colour> {}; + + template + struct redim_type< + srgba + > { template using type = srgba<_S,T>; }; + + template + struct revalue_type> { + template + using type = srgba; + }; + + + template struct is_colour : public std::false_type {}; + template < + size_t S, + typename T, + template < + size_t, + typename + > typename ColourT + > struct is_colour> + :std::conditional_t< + std::is_base_of_v< + colour>, + ColourT + >, + std::true_type, + std::false_type + > {}; + + + template + constexpr auto is_colour_v = is_colour::value; } #include "colour.ipp" diff --git a/colour.ipp b/colour.ipp index 37b8f2eb..0f334864 100644 --- a/colour.ipp +++ b/colour.ipp @@ -19,15 +19,3 @@ #endif #define __UTIL_COLOUR_IPP -template -template -util::colour -util::colour::cast (void) const -{ - colour ret; - std::transform (this->begin (), - this->end (), - ret.begin (), - renormalise); - return ret; -} diff --git a/coord/base.hpp b/coord/base.hpp index bc3c0d65..81065d44 100644 --- a/coord/base.hpp +++ b/coord/base.hpp @@ -17,44 +17,56 @@ #ifndef __UTIL_COORD_BASE_HPP #define __UTIL_COORD_BASE_HPP +#include "fwd.hpp" + #include "init.hpp" +#include "traits.hpp" #include "../maths.hpp" #include #include #include + namespace util::coord { ///////////////////////////////////////////////////////////////////////// + // the base class for all coordinate-like types. + // + // SelfT should not be exposed as a template template directly because + // some types (eg, XYZ colours) do not conform to the same template + // parameters are others (eg, vector2f). ie, it does not make sense to + // allow redim, or type changing on some types so they just aren't exposed. template < size_t S, typename T, - template class KLASS, - typename ...tags + typename SelfT > - struct base : public init { + struct base : public init { static_assert (S > 0); static_assert (std::is_arithmetic::value); + static_assert (sizeof (init) == S * sizeof (T)); using value_type = T; static constexpr size_t dimension = S; static constexpr size_t elements = S; - static constexpr size_t size (void) { return S; } + static constexpr auto size (void) { return S; } // constructors - using init::init; + using init::init; base () = default; constexpr explicit base (T val) { std::fill (begin (), end (), val); } - constexpr base (const base &rhs) = default; - base& operator= (const base &rhs) = default; + constexpr base (const base &rhs) = default; + base& operator= (const base &rhs) = default; // element accessors T& operator[] (size_t i) { return this->data[i]; } constexpr const T& operator[] (size_t i) const { return this->data[i]; } + T& operator[] (int i) { return this->data[i]; } + constexpr const T& operator[] (int i) const { return this->data[i]; } auto cbegin (void) const { return std::cbegin (this->data); } auto cend (void) const { return std::cend (this->data); } @@ -81,12 +93,28 @@ namespace util::coord { return k; } + + //--------------------------------------------------------------------- + template < + typename K, + typename = std::enable_if_t,void> + > + K as (void) const + { + static_assert (K::elements == elements); + K k; + std::copy (begin (), end (), k.begin ()); + return k; + } + + //--------------------------------- template - KLASS + auto cast (void) const { - KLASS out; + typename revalue_type::template type out; + std::copy (std::cbegin (this->data), std::cend (this->data), std::begin (out.data)); @@ -95,11 +123,18 @@ namespace util::coord { /////////////////////////////////////////////////////////////////////// // redimension - template - KLASS + template < + size_t D, + typename _sfinae = SelfT + > + std::enable_if_t< + has_redim_v<_sfinae>, + redim_t<_sfinae,D> + > redim (void) const { - KLASS out; + redim_t out; + std::copy_n (std::cbegin (this->data), min (S, D), std::begin (out.data)); @@ -108,11 +143,14 @@ namespace util::coord { //--------------------------------------------------------------------- - template - KLASS - redim (const KLASS fill) const + template + std::enable_if_t< + has_redim_v<_sfinae>, + redim_t<_sfinae,D> + > + redim (const redim_t<_sfinae,D> fill) const { - KLASS out; + redim_t out; static constexpr auto L1 = min (S, D); static constexpr auto L2 = D - L1; @@ -128,11 +166,17 @@ namespace util::coord { } //--------------------------------------------------------------------- - template - KLASS + template < + size_t D, + typename _sfinae = SelfT + > + std::enable_if_t< + has_redim_v<_sfinae>, + redim_t<_sfinae,D> + > redim (T fill) const { - KLASS out; + redim_t out; auto cursor = std::copy_n (std::cbegin (this->data), min (S, D), @@ -144,5 +188,6 @@ namespace util::coord { }; } +#include "ops.hpp" #endif diff --git a/coord/fwd.hpp b/coord/fwd.hpp index e1c3347e..fcd41a8a 100644 --- a/coord/fwd.hpp +++ b/coord/fwd.hpp @@ -14,11 +14,20 @@ * Copyright 2016 Danny Robson */ -#ifndef __UTIL_COORD_FWD_HPP -#define __UTIL_COORD_FWD_HPP +#ifndef CRUFT_UTIL_COORD_FWD_HPP +#define CRUFT_UTIL_COORD_FWD_HPP + +#include namespace util { - template struct colour; + namespace coord { + template struct store; + template struct init; + template struct base; + } + + template struct srgba; + template struct hsva; template struct extent; template struct point; template struct vector; diff --git a/coord/init.hpp b/coord/init.hpp index 5423e75b..478bcd0b 100644 --- a/coord/init.hpp +++ b/coord/init.hpp @@ -22,53 +22,53 @@ #include namespace util::coord { - template + template struct init; //------------------------------------------------------------------------- - template - struct init<1,T,tags...> : public store<1,T,tags...> + template + struct init<1,T,SelfT> : public store<1,T,SelfT> { - using store<1,T,tags...>::store; + using store<1,T,SelfT>::store; constexpr init () = default; constexpr init (T v0): - store<1,T,tags...> ({v0}) + store<1,T,SelfT> ({v0}) { ; } }; //------------------------------------------------------------------------- - template - struct init<2,T,tags...> : public store<2,T,tags...> + template + struct init<2,T,SelfT> : public store<2,T,SelfT> { - using store<2,T,tags...>::store; + using store<2,T,SelfT>::store; constexpr init () = default; constexpr init (T v0, T v1): - store<2,T,tags...> ({ v0, v1 }) + store<2,T,SelfT> ({ v0, v1 }) { ; } }; //------------------------------------------------------------------------- - template - struct init<3,T,tags...> : public store<3,T,tags...> + template + struct init<3,T,SelfT> : public store<3,T,SelfT> { - using store<3,T,tags...>::store; + using store<3,T,SelfT>::store; constexpr init () = default; constexpr init (T v0, T v1, T v2): - store<3,T,tags...> ({v0, v1, v2}) + store<3,T,SelfT> ({v0, v1, v2}) { ; } }; //------------------------------------------------------------------------- - template - struct init<4,T,tags...> : public store<4,T,tags...> + template + struct init<4,T,SelfT> : public store<4,T,SelfT> { - using store<4,T,tags...>::store; + using store<4,T,SelfT>::store; constexpr init () = default; constexpr init (T v0, T v1, T v2, T v3): - store<4,T,tags...> ({ v0, v1, v2, v3 }) + store<4,T,SelfT> ({ v0, v1, v2, v3 }) { ; } }; } diff --git a/coord/iostream.hpp b/coord/iostream.hpp index c95b0d7f..2d1a4eac 100644 --- a/coord/iostream.hpp +++ b/coord/iostream.hpp @@ -24,8 +24,8 @@ namespace util { template < - template class K, - size_t S, + template class K, + std::size_t S, typename T > std::ostream& diff --git a/coord/names.hpp b/coord/names.hpp deleted file mode 100644 index d34dec13..00000000 --- a/coord/names.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright 2015 Danny Robson - */ - -#ifndef __UTIL_COORD_NAMES_HPP -#define __UTIL_COORD_NAMES_HPP - -namespace util::coord { - /////////////////////////////////////////////////////////////////////// - // tags for accessor names - // - // colours - struct rgba { }; - struct hsv { }; - - // physical positions - struct xyzw { }; - - // texture coords - struct stpq { }; - - // physical dimensions - struct whd { }; - - // quaternions - struct wxyz { }; - struct abcd { }; -} - -#endif diff --git a/coord/ops.hpp b/coord/ops.hpp index 9d6a36ab..f5b52ef7 100644 --- a/coord/ops.hpp +++ b/coord/ops.hpp @@ -18,6 +18,7 @@ #define __UTIL_COORDS_OPS #include "fwd.hpp" +#include "traits.hpp" #include "../debug.hpp" #include "../maths.hpp" @@ -28,245 +29,273 @@ #include #include #include +#include namespace util { - /////////////////////////////////////////////////////////////////////// - // operation traits - namespace coord { - template < - template class A, - template class B - > - struct result { }; - - //------------------------------------------------------------------------- - template <> struct result { template using type = colour; }; - template <> struct result { template using type = extent; }; - template <> struct result { template using type = extent; }; - template <> struct result { template using type = point ; }; - template <> struct result { template using type = point ; }; - template <> struct result { template using type = point ; }; - template <> struct result { template using type = vector; }; - - template < - template class A, - template class B - > - using result_t = typename result::type; - - - //--------------------------------------------------------------------- - template