Looking at the way you implement constexpr, I actually managed to figure out a more efficient method of creating consts without the use of a static variable.
Code: Select all
namespace Colors
{
template<unsigned char r, unsigned char g, unsigned char b>
struct MakeRGB
{
static constexpr Color Value()
{
return (r << 16) | (g << 8) | b;
}
};
using White = MakeRGB< 255u, 255u, 255u >;
using Black = MakeRGB< 0u, 0u, 0u >;
using Gray = MakeRGB< 0x80u, 0x80u, 0x80u >;
using LightGray = MakeRGB< 0xD3u, 0xD3u, 0xD3u >;
using Red = MakeRGB< 255u, 0u, 0u >;
using Green = MakeRGB< 0u, 255u, 0u >;
using Blue = MakeRGB< 0u, 0u, 255u >;
using Yellow = MakeRGB< 255u, 255u, 0u >;
using Cyan = MakeRGB< 0u, 255u, 255u >;
using Magenta = MakeRGB< 255u, 0u, 255u >;
}
Code: Select all
gfx.PutPixel( x,y,Colors::Red::Value() );
In theory, this has three advantages. One, it makes sure that the compiler optimises the code by inlining the result in straight away(there are some cases where it won't do that with static constexpr for certain runtime code.) Also, it saves memory as the compiler does usually save the value of the static as a variable in the code for runtime especially if you accidentally save a reference of it in code. This should also prevent you from doing that unnecessary as shown here.
Code: Select all
static constexpr Color c = MakeRGB<0, 0, 0>::Result();
void Do(Color const* i)
{
//impossible with template function
i = &White::Value();
//still possible with static constexpr
i = &c;
}
Really, the only disadvantage is that you need to type more just to get the value and you still need to make another MakeRGB function for runtime. In any case, I also made a basic struct to handle simple intrinsic type consts.
Code: Select all
template<class Type, Type value>
struct IntrinsicConst
{
static constexpr Type Value()
{
return value;
}
};
Code: Select all
private:
using bufferSize = IntrinsicConst<unsigned int, 4u>;
-Zekilk