Make 'Color' a 'constexpr' class

This commit is contained in:
Vittorio Romeo 2021-12-18 19:58:23 +01:00
parent cfeb7651b5
commit ed201ce87a
4 changed files with 174 additions and 131 deletions

View File

@ -37,7 +37,7 @@ namespace sf
/// \brief Utility class for manipulating RGBA colors
///
////////////////////////////////////////////////////////////
class SFML_GRAPHICS_API Color
class Color
{
public:
@ -48,7 +48,7 @@ public:
/// sf::Color(0, 0, 0, 255).
///
////////////////////////////////////////////////////////////
Color();
constexpr Color();
////////////////////////////////////////////////////////////
/// \brief Construct the color from its 4 RGBA components
@ -59,7 +59,7 @@ public:
/// \param alpha Alpha (opacity) component (in the range [0, 255])
///
////////////////////////////////////////////////////////////
Color(Uint8 red, Uint8 green, Uint8 blue, Uint8 alpha = 255);
constexpr Color(Uint8 red, Uint8 green, Uint8 blue, Uint8 alpha = 255);
////////////////////////////////////////////////////////////
/// \brief Construct the color from 32-bit unsigned integer
@ -67,7 +67,7 @@ public:
/// \param color Number containing the RGBA components (in that order)
///
////////////////////////////////////////////////////////////
explicit Color(Uint32 color);
constexpr explicit Color(Uint32 color);
////////////////////////////////////////////////////////////
/// \brief Retrieve the color as a 32-bit unsigned integer
@ -75,20 +75,20 @@ public:
/// \return Color represented as a 32-bit unsigned integer
///
////////////////////////////////////////////////////////////
Uint32 toInteger() const;
constexpr Uint32 toInteger() const;
////////////////////////////////////////////////////////////
// Static member data
////////////////////////////////////////////////////////////
static const Color Black; //!< Black predefined color
static const Color White; //!< White predefined color
static const Color Red; //!< Red predefined color
static const Color Green; //!< Green predefined color
static const Color Blue; //!< Blue predefined color
static const Color Yellow; //!< Yellow predefined color
static const Color Magenta; //!< Magenta predefined color
static const Color Cyan; //!< Cyan predefined color
static const Color Transparent; //!< Transparent (black) predefined color
SFML_GRAPHICS_API static const Color Black; //!< Black predefined color
SFML_GRAPHICS_API static const Color White; //!< White predefined color
SFML_GRAPHICS_API static const Color Red; //!< Red predefined color
SFML_GRAPHICS_API static const Color Green; //!< Green predefined color
SFML_GRAPHICS_API static const Color Blue; //!< Blue predefined color
SFML_GRAPHICS_API static const Color Yellow; //!< Yellow predefined color
SFML_GRAPHICS_API static const Color Magenta; //!< Magenta predefined color
SFML_GRAPHICS_API static const Color Cyan; //!< Cyan predefined color
SFML_GRAPHICS_API static const Color Transparent; //!< Transparent (black) predefined color
////////////////////////////////////////////////////////////
// Member data
@ -111,7 +111,7 @@ public:
/// \return True if colors are equal, false if they are different
///
////////////////////////////////////////////////////////////
SFML_GRAPHICS_API bool operator ==(const Color& left, const Color& right);
[[nodiscard]] constexpr bool operator ==(const Color& left, const Color& right);
////////////////////////////////////////////////////////////
/// \relates Color
@ -125,7 +125,7 @@ SFML_GRAPHICS_API bool operator ==(const Color& left, const Color& right);
/// \return True if colors are different, false if they are equal
///
////////////////////////////////////////////////////////////
SFML_GRAPHICS_API bool operator !=(const Color& left, const Color& right);
[[nodiscard]] constexpr bool operator !=(const Color& left, const Color& right);
////////////////////////////////////////////////////////////
/// \relates Color
@ -140,7 +140,7 @@ SFML_GRAPHICS_API bool operator !=(const Color& left, const Color& right);
/// \return Result of \a left + \a right
///
////////////////////////////////////////////////////////////
SFML_GRAPHICS_API Color operator +(const Color& left, const Color& right);
[[nodiscard]] constexpr Color operator +(const Color& left, const Color& right);
////////////////////////////////////////////////////////////
/// \relates Color
@ -155,7 +155,7 @@ SFML_GRAPHICS_API Color operator +(const Color& left, const Color& right);
/// \return Result of \a left - \a right
///
////////////////////////////////////////////////////////////
SFML_GRAPHICS_API Color operator -(const Color& left, const Color& right);
[[nodiscard]] constexpr Color operator -(const Color& left, const Color& right);
////////////////////////////////////////////////////////////
/// \relates Color
@ -172,7 +172,7 @@ SFML_GRAPHICS_API Color operator -(const Color& left, const Color& right);
/// \return Result of \a left * \a right
///
////////////////////////////////////////////////////////////
SFML_GRAPHICS_API Color operator *(const Color& left, const Color& right);
[[nodiscard]] constexpr Color operator *(const Color& left, const Color& right);
////////////////////////////////////////////////////////////
/// \relates Color
@ -188,7 +188,7 @@ SFML_GRAPHICS_API Color operator *(const Color& left, const Color& right);
/// \return Reference to \a left
///
////////////////////////////////////////////////////////////
SFML_GRAPHICS_API Color& operator +=(Color& left, const Color& right);
constexpr Color& operator +=(Color& left, const Color& right);
////////////////////////////////////////////////////////////
/// \relates Color
@ -204,7 +204,7 @@ SFML_GRAPHICS_API Color& operator +=(Color& left, const Color& right);
/// \return Reference to \a left
///
////////////////////////////////////////////////////////////
SFML_GRAPHICS_API Color& operator -=(Color& left, const Color& right);
constexpr Color& operator -=(Color& left, const Color& right);
////////////////////////////////////////////////////////////
/// \relates Color
@ -222,7 +222,9 @@ SFML_GRAPHICS_API Color& operator -=(Color& left, const Color& right);
/// \return Reference to \a left
///
////////////////////////////////////////////////////////////
SFML_GRAPHICS_API Color& operator *=(Color& left, const Color& right);
constexpr Color& operator *=(Color& left, const Color& right);
#include <SFML/Graphics/Color.inl>
} // namespace sf

View File

@ -0,0 +1,149 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2021 Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
constexpr Color::Color() :
r(0),
g(0),
b(0),
a(255)
{
}
////////////////////////////////////////////////////////////
constexpr Color::Color(Uint8 red, Uint8 green, Uint8 blue, Uint8 alpha) :
r(red),
g(green),
b(blue),
a(alpha)
{
}
////////////////////////////////////////////////////////////
constexpr Color::Color(Uint32 color) :
r(static_cast<Uint8>((color & 0xff000000) >> 24)),
g(static_cast<Uint8>((color & 0x00ff0000) >> 16)),
b(static_cast<Uint8>((color & 0x0000ff00) >> 8)),
a(static_cast<Uint8>(color & 0x000000ff))
{
}
////////////////////////////////////////////////////////////
constexpr Uint32 Color::toInteger() const
{
return static_cast<Uint32>((r << 24) | (g << 16) | (b << 8) | a);
}
////////////////////////////////////////////////////////////
constexpr bool operator ==(const Color& left, const Color& right)
{
return (left.r == right.r) &&
(left.g == right.g) &&
(left.b == right.b) &&
(left.a == right.a);
}
////////////////////////////////////////////////////////////
constexpr bool operator !=(const Color& left, const Color& right)
{
return !(left == right);
}
////////////////////////////////////////////////////////////
constexpr Color operator +(const Color& left, const Color& right)
{
const auto clampedAdd = [](Uint8 lhs, Uint8 rhs) -> Uint8
{
const int intResult = static_cast<int>(lhs) + static_cast<int>(rhs);
return static_cast<Uint8>(intResult < 255 ? intResult : 255);
};
return Color(clampedAdd(left.r, right.r),
clampedAdd(left.g, right.g),
clampedAdd(left.b, right.b),
clampedAdd(left.a, right.a));
}
////////////////////////////////////////////////////////////
constexpr Color operator -(const Color& left, const Color& right)
{
const auto clampedSub = [](Uint8 lhs, Uint8 rhs) -> Uint8
{
const int intResult = static_cast<int>(lhs) - static_cast<int>(rhs);
return static_cast<Uint8>(intResult > 0 ? intResult : 0);
};
return Color(clampedSub(left.r, right.r),
clampedSub(left.g, right.g),
clampedSub(left.b, right.b),
clampedSub(left.a, right.a));
}
////////////////////////////////////////////////////////////
constexpr Color operator *(const Color& left, const Color& right)
{
const auto scaledMul = [](Uint8 lhs, Uint8 rhs) -> Uint8
{
const auto uint16Result = static_cast<Uint16>(static_cast<Uint16>(lhs) * static_cast<Uint16>(rhs));
return static_cast<Uint8>(uint16Result / 255u);
};
return Color(scaledMul(left.r, right.r),
scaledMul(left.g, right.g),
scaledMul(left.b, right.b),
scaledMul(left.a, right.a));
}
////////////////////////////////////////////////////////////
constexpr Color& operator +=(Color& left, const Color& right)
{
return left = left + right;
}
////////////////////////////////////////////////////////////
constexpr Color& operator -=(Color& left, const Color& right)
{
return left = left - right;
}
////////////////////////////////////////////////////////////
constexpr Color& operator *=(Color& left, const Color& right)
{
return left = left * right;
}

View File

@ -8,6 +8,7 @@ set(SRC
${INCROOT}/BlendMode.hpp
${SRCROOT}/Color.cpp
${INCROOT}/Color.hpp
${INCROOT}/Color.inl
${INCROOT}/Export.hpp
${SRCROOT}/Font.cpp
${INCROOT}/Font.hpp

View File

@ -26,7 +26,6 @@
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics/Color.hpp>
#include <algorithm>
namespace sf
@ -44,112 +43,4 @@ const Color Color::Magenta(255, 0, 255);
const Color Color::Cyan(0, 255, 255);
const Color Color::Transparent(0, 0, 0, 0);
////////////////////////////////////////////////////////////
Color::Color() :
r(0),
g(0),
b(0),
a(255)
{
}
////////////////////////////////////////////////////////////
Color::Color(Uint8 red, Uint8 green, Uint8 blue, Uint8 alpha) :
r(red),
g(green),
b(blue),
a(alpha)
{
}
////////////////////////////////////////////////////////////
Color::Color(Uint32 color) :
r(static_cast<Uint8>((color & 0xff000000) >> 24)),
g(static_cast<Uint8>((color & 0x00ff0000) >> 16)),
b((color & 0x0000ff00) >> 8 ),
a((color & 0x000000ff) >> 0 )
{
}
////////////////////////////////////////////////////////////
Uint32 Color::toInteger() const
{
return static_cast<Uint32>((r << 24) | (g << 16) | (b << 8) | a);
}
////////////////////////////////////////////////////////////
bool operator ==(const Color& left, const Color& right)
{
return (left.r == right.r) &&
(left.g == right.g) &&
(left.b == right.b) &&
(left.a == right.a);
}
////////////////////////////////////////////////////////////
bool operator !=(const Color& left, const Color& right)
{
return !(left == right);
}
////////////////////////////////////////////////////////////
Color operator +(const Color& left, const Color& right)
{
return Color(Uint8(std::min(int(left.r) + right.r, 255)),
Uint8(std::min(int(left.g) + right.g, 255)),
Uint8(std::min(int(left.b) + right.b, 255)),
Uint8(std::min(int(left.a) + right.a, 255)));
}
////////////////////////////////////////////////////////////
Color operator -(const Color& left, const Color& right)
{
return Color(Uint8(std::max(int(left.r) - right.r, 0)),
Uint8(std::max(int(left.g) - right.g, 0)),
Uint8(std::max(int(left.b) - right.b, 0)),
Uint8(std::max(int(left.a) - right.a, 0)));
}
////////////////////////////////////////////////////////////
Color operator *(const Color& left, const Color& right)
{
return Color(Uint8(int(left.r) * right.r / 255),
Uint8(int(left.g) * right.g / 255),
Uint8(int(left.b) * right.b / 255),
Uint8(int(left.a) * right.a / 255));
}
////////////////////////////////////////////////////////////
Color& operator +=(Color& left, const Color& right)
{
return left = left + right;
}
////////////////////////////////////////////////////////////
Color& operator -=(Color& left, const Color& right)
{
return left = left - right;
}
////////////////////////////////////////////////////////////
Color& operator *=(Color& left, const Color& right)
{
return left = left * right;
}
} // namespace sf