Sunday, 4 September 2011

ZX Spectrum Fine Art 3

I'm finding this very therapeutic, but I may have bitten off a bit too much this time:


Saturday, 2 July 2011

ZX Spectrum Fine Art 2

Following the resounding critical success of my last piece of ZX Spectrum Fine Art ("I rather like it"), I bring you an interpretation of "The Billy Boys" by Jack Vettriano. See if you can tell which is the original:

Saturday, 11 June 2011

Comparison Operand Stripping in C++

If you're writing C++ assertions or unit tests, you'll have written code similar to:
ASSERT(a < b);
or
if (!VERIFY(a != b)) { ... }
If you're running without a debugger attached or with optimisations fully on, you'll get the usual error report, but no idea what the underlying values are or were:
test.cpp(1): Failed VERIFY(a != b)
Wouldn't it be wonderful if it did? Up until recently, I thought the only way of achieving that was to use ugly macros of the forms:
ASSERT_OP(a, <, b);
ASSERT_LT(a, b);
 which, if you're lucky, will produce output similar to:
test.cpp(2): Failed ASSERT(a < b)
    'a' is 321
    'b' is 123
The only problem is that it's extremely ugly. There must be a better way, surely? But it's C++: there's always an alternative, no matter how convoluted internally. Consider operator precedence:
something << a < b >> something
This will evaluate 'something << a' first, then 'b >> something', and then apply the less-than operation to the results. Now consider:
namespace Verify
{
    struct Outer;
    template<typename T>
    struct Inner
    {
        const T& value;
        explicit Inner(const T& inner) :
            value(inner) {}
    };
    template<typename T>
    Inner<T> operator<<(const Outer&,
                        const T& inner)
    {
        return Inner<T>(inner);
    }
    template<typename T>
    Inner<T> operator>>(const T& inner,
                        const Outer&)
    {
        return Inner<T>(inner);
    }
}
Note that 'Outer' is not defined, only declared; we're only going to use its type information:
#define CHILLIANT_OUTER \
    (*(Verify::Outer*)nullptr)
#define CHILLIANT_VERIFY(expr) /
    CHILLIANT_BLAH(CHILLIANT_OUTER << expr >>\
                   CHILLIANT_OUTER)
But what's the defintion of 'CHILLIANT_BLAH()'? Well, we want to report the location of any failure along with the expression text:
#define CHILLIANT_VERIFY(expr) /
    (Verify::Report(__FILE__,__LINE__,#expr, \
        (CHILLIANT_OUTER << expr >>\
         CHILLIANT_OUTER)))
The type of the final argument to 'Verify::Report()' can be one of three things:
  1. The result of a binary comparison (including encapsulations of the two operand values),
  2. A single value (and an encapsulation of that value) that can be utilised as a Boolean condition, and
  3. A Boolean value (for cases where we cannot easily determine the encapsulations).
The third case should be redundant, but for simplicity we're not going to handle complex cases such as 'a < b && c > d' here. That's left as an exercise for the reader.
namespace Verify
{
    template<typename L,typename R>
    bool Report(/*blah*/,
                const Binary<L,R>& result)
    {
        if (!result.condition)
        {
            /*blah*/
        }
        return result.condition;
    }
    template<typename T>
    bool Report(/*blah*/,
                const Unary<T>& result)
    {
        if (!result.condition)
        {
            /*blah*/
        }
        return result.condition;
    }
    bool Report(/*blah*/,
                bool result)
    {
        if (!result)
        {
            /*blah*/
        }
        return result;
    }
}
Now all that remains is the code to glue the three condition types to the three reporting functions. Firstly, binary comparison operations:
namespace Verify
{
    template<typename L,typename R>
    struct Binary
    {
        bool condition;
        const char* operation;
        const Inner<L>& lhs;
        const Inner<R>& rhs;
        Binary(bool result,
               const char* op,
               const Inner<L>& left,
               const Inner<R>& right) :
            condition(result),
            operation(op),
            lhs(left),
            rhs(right) {}
    };
    template<typename L,typename R>
    Binary<L,R> operator<(const Inner<L>& lhs,
                          const Inner<R>& rhs)
    {
        return Binary<L,R>(
            lhs.value < rhs.value,
            "<", lhs, rhs);
    }
    /* Similarly for <=, ==, !=, > and >= */
}
This will be invoked for expressions such as 'x < y' and even 'x*2 < y+1'. But we also want to handle expressions without comparison operators:
namespace Verify
{
    template<typename T>
    struct Unary
    {
        bool condition;
        const Inner<T>& value;
        Unary(bool result,
              const Inner<T>& inner) :
            condition(result),
            value(inner) {}
    };
    template<typename T>
    Unary<T> operator>>(const Inner<T>& inner,
                        const Outer&)
    {
        return Unary<T>(inner.value, inner);
    }
}
Finally, we must deal with expressions that use operators that "fall between the gaps" (i.e. have lower precedence than the comparison operators, such as '&&'). A good catch-all is to allow 'Inner<T>' to implicitly convert to its underlying type 'T':
namespace Verify
{
    template<typename T>
    struct Inner
    {
        const T& value;
        explicit Inner(const T& inner) :
            value(inner) {}
        operator T() const { return value; }
    };
}
Adding type-safe helper functions to help with reporting and putting everything together, we end up with the following:
namespace Verify
{
    void Output(const char* fmt, ...);
    struct Outer;
    template<typename T>
    struct Inner
    {
        const T& value;
        explicit Inner(const T& inner) :
            value(inner) {}
        operator T() const { return value; }
        void Output(const char* label) const;
    };
    template<typename T>
    Inner<T> operator<<(const Outer&,
                        const T& inner)
    {
        return Inner<T>(inner);
    }
    template<typename T>
    Inner<T> operator>>(const T& inner,
                        const Outer&)
    {
        return Inner<T>(inner);
    }
    template<typename T>
    struct Unary
    {
        bool condition;
        const Inner<T>& value;
        Unary(bool result,
              const Inner<T>& inner) :
            condition(result),
            value(inner) {}
    };
    template<typename T>
    Unary<T> operator>>(const Inner<T>& inner,
                        const Outer&)
    {
        return Unary<T>(inner.value, inner);
    }
    template<typename L,typename R>
    struct Binary
    {
        bool condition;
        const char* operation;
        const Inner<L>& lhs;
        const Inner<R>& rhs;
        Binary(bool result, const char* op,
               const Inner<L>& left,
               const Inner<R>& right) :
            condition(result),
            operation(op),
            lhs(left),
            rhs(right) {}
    };
    template<typename L,typename R>
    Binary<L,R> operator<(
        const Inner<L>& lhs,
        const Inner<R>& rhs)
    {
        return Binary<L,R>(
            lhs.value < rhs.value,
            "<", lhs, rhs);
    }
    template<typename L,typename R>
    Binary<L,R> operator<=(
        const Inner<L>& lhs,
        const Inner<R>& rhs)
    {
        return Binary<L,R>(
            lhs.value <= rhs.value,
            "<=", lhs, rhs);
    }
    template<typename L,typename R>
    Binary<L,R> operator>(
        const Inner<L>& lhs,
        const Inner<R>& rhs)
    {
        return Binary<L,R>(
            lhs.value > rhs.value,
            ">", lhs, rhs);
    }
    template<typename L,typename R>
    Binary<L,R> operator>=(
        const Inner<L>& lhs,
        const Inner<R>& rhs)
    {
        return Binary<L,R>(
            lhs.value >= rhs.value,
            ">=", lhs, rhs);
    }
    template<typename L,typename R>
    Binary<L,R> operator==(
        const Inner<L>& lhs,
        const Inner<R>& rhs)
    {
        return Binary<L,R>(
            lhs.value == rhs.value,
            "==", lhs, rhs);
    }
    template<typename L,typename R>
    Binary<L,R> operator!=(
        const Inner<L>& lhs,
        const Inner<R>& rhs)
    {
        return Binary<L,R>(
            lhs.value != rhs.value,
            "!=", lhs, rhs);
    }
    bool Report(const char* file, long line,
                const char* expression,
                bool result)
    {
        if (!result)
        {
            Output("%s(%ld): Failed "
                   "CHILLIANT_VERIFY(%s)\n",
                   file, line, expression);
            Inner<bool> value(false);
            value.Output("value");
        }
        return result;
    }
    template<typename T>
    bool Report(const char* file, long line,
                const char* expression,
                const Unary<T>& result)
    {
        if (!result.condition)
        {
            Output("%s(%ld): Failed "
                   "CHILLIANT_VERIFY(%s)\n",
                   file, line, expression);
            result.value.Output("value");
        }
        return result.condition;
    }
    template<typename L,typename R>
    bool Report(const char* file, long line,
                const char* expression,
                const Binary<L,R>& result)
    {
        if (!result.condition)
        {
            Output("%s(%ld): Failed "
                   "CHILLIANT_VERIFY(%s)\n",
                   file, line, expression);
            Output("    for "
                   "(LHS %s RHS)"
                   " where\n",
                   result.operation);
            result.lhs.Output("LHS");
            result.rhs.Output("RHS");
        }
        return result.condition;
    }
}
#define CHILLIANT_VERIFY_OUTER \
    (*(Verify::Outer*)nullptr)
#define CHILLIANT_VERIFY(expr) \
    (Verify::Report(__FILE__,__LINE__,#expr,\
        (CHILLIANT_VERIFY_OUTER << expr >>\
         CHILLIANT_VERIFY_OUTER)))
Now we can write reporters (including for user-defined types) and perform checks such as the following:
template<>
void Verify::Inner<bool>::
    Output(const char* label) const
{
    Verify::Output("   %s is %s (bool)\n",
                   label,
                   value ? "true" : "false");
}
template<>
void Verify::Inner<int>::
   
Output(const char* label) const
{
    Verify::Output("   %s is %d (int)\n",
                   label,
                   value);
}
template<>
void Verify::Inner<float>::
   
Output(const char* label) const
{
    Verify::Output("   %s is %g (float)\n",
                   label,
                   value);
}

void TestVerify(void)
{
    int i = 3;
    float f = 3.14159f;
    if (!CHILLIANT_VERIFY(false)) ...
    if (!CHILLIANT_VERIFY(i > 0 && i < 2)) ...
    if (!CHILLIANT_VERIFY(12 * 6 < i + 7)) ...
    if (!CHILLIANT_VERIFY(12 * 6 > f * 1000)) ...
}
This will produce the following output:
test.cpp(101): Failed CHILLIANT_VERIFY(false)
    value is false (bool)
test.cpp(102): Failed CHILLIANT_VERIFY(i > 0 && i < 2)
    value is false (bool)
test.cpp(103): Failed CHILLIANT_VERIFY(12 * 6 < i + 7)
    for CHILLIANT_VERIFY(LHS < RHS) where
    LHS is 72 (int)
    RHS is 10 (int)
test.cpp(104): Failed CHILLIANT_VERIFY(12 * 6 > f * 1000)
    for CHILLIANT_VERIFY(LHS > RHS) where
    LHS is 72 (int)
    RHS is 3141.59 (float)
The nice thing about this "comparison operand stripping" pattern is that you can turn the feature on and off at will, without jumping through syntactic hoops:
#define CHILLIANT_VERIFY(expr) (expr)
It can also be extended to assertions. What's not to like?

Saturday, 21 May 2011

You Looking At Me? T-Shirt

static_assert and the C++ Preprocessor

With a title like that, you know you're in for a bit of geekiness.

With C++0x we now have proper static asserts. Hurrah! Except I don't like them. Their syntax is:

static_assert(sizeof(int) < 5, "Integers too big");

To me, the second argument is extra fluff that should be optional, but isn't. Perhaps we can get around it with preprocessor macros:

STATIC_ASSERT(sizeof(int) < 5, "Integers too big");
STATIC_ASSERT(sizeof(int) < 5);

But how do we overload preprocessor macros? With the help of variadic macros it is (just about) possible to overload based on the number of arguments. Ironically, this is much easier with the C99 preprocessor than with the current C++ one; all the solutions for C++ that I've seen need tweaking for different compilers. The code below works for Microsoft C++ 2010.

As an aside, Jens Gustedt has produced an amazing (and instructive) set of C99 preprocessor macros called P99. Well worth a look.

But for our C++ case, we want to construct something along the lines of:

#define STATIC_ASSERT(condition, ...) \
    if (__VA_ARGS__ is empty) then \
        static_assert(condition, #condition) \
    else \
        static_assert(condition, __VA_ARGS__)

There are two problems here: (a) how to determine if there are additional arguments, and (b) achieving an if-then-else structure in a macro that's fully resolved by the preprocessor.

The first problem can be solved using a technique I first saw in a reply to a question on stackoverflow:

#define CHILLIANT_LITERAL(...) __VA_ARGS__
#define CHILLIANT_VA_PICK__(a,b,c,d,e,f,g,h,i,j,...) j
#define CHILLIANT_VA_PICK_(a) \

    CHILLIANT_LITERAL(CHILLIANT_VA_PICK__)a
#define CHILLIANT_VA_PICK(a,b,...) \

    CHILLIANT_VA_PICK_((a##__VA_ARGS__##b,a##b))
#define CHILLIANT_VA_EMPTY__YTPME_AV_TNAILLIHC 0,0,0,0,0,0,0,0,0,1
#define CHILLIANT_VA_EMPTY(...) \

    CHILLIANT_VA_PICK(CHILLIANT_VA_EMPTY_, \
        _YTPME_AV_TNAILLIHC,__VA_ARGS__)

How this actually works is left as an exercise for the reader, but the bottom line is that "CHILLIANT_VA_EMPTY(...)" called with no arguments resolves to the token "1", whilst one or more arguments causes it to resolve to "0". The above code snippet only works for up to nine arguments, but it is trivial to expand to a greater number.

For completeness, here's the macro to return the count of the number of arguments:

#define CHILLIANT_VA_COUNT__TNUOC_AV_TNAILLIHC 9,8,7,6,5,4,3,2,1,0
#define CHILLIANT_VA_COUNT(...) \

    CHILLIANT_VA_PICK(CHILLIANT_VA_COUNT_, \
        _TNUOC_AV_TNAILLIHC,__VA_ARGS__)

Groovy, huh?

The second problem, generating the if-then-else semantic, is made difficult because we want it to resolve during the preprocessor phase, not during compilation. However, if we assume the condition is only ever the token "0" or "1" (which it is) the problem can be solved with careful identifier concatenation:

#define CHILLIANT_IGNORE(...)
#define CHILLIANT_IF_0(...) CHILLIANT_LITERAL
#define CHILLIANT_IF_1(...) __VA_ARGS__ CHILLIANT_IGNORE
#define CHILLIANT_IF(condition) \

    CHILLIANT_LITERAL(CHILLIANT_IF_)##CHILLIANT_LITERAL(condition)

This is used as follows:

CHILLIANT_IF(condition)(then_clause)(else_clause)

Now, we can construct the definition of "STATIC_ASSERT()":

#define STATIC_ASSERT(condition, ...) \
    static_assert(condition, \
        CHILLIANT_IF(CHILLIANT_VA_EMPTY(__VA_ARGS__)) \
            (#condition) \
            (__VA_ARGS__))

This does seem to be a lot of trouble to go to just to make the second argument of a static assert optional, but now you also have some of the basic building blocks to really go to town with the preprocessor.

Saturday, 16 April 2011

DAB Clock Radio Mod

I recently took the (somewhat conservative) plunge and went shopping for a DAB clock radio for my beside table. They all seemed rather expensive for what you get, except for one model which my local "evil" supermarket was selling off for £10. No-one at the store seemed to know why they were selling it off for a fraction of its retail price, so I snapped one up on the off-chance.

After getting it home, it quickly became apparent that there was a fundamental design flaw: the backlight is far too bright for a bedside table, even on its "dim" setting. This seems to be a common complaint with many new DAB clock radios. But with just a screwdriver and long-nosed pliers there is a solution...

The following instructions are for the "Technika CR-109IDAB" device, but I'm guessing they're all pretty much of a pattern. Your warrantee will be invalidated, of course.
  1. Remove the six crosshead screws from the base.
  2. Remove the two crosshead screws holding the LCD module to the front panel.
  3. Carefully unclip the front panel and, using long-nosed pliers, bend the legs of the two LEDs on the right-hand side of the display module, so that the LEDs face forward, instead of "into" the module. Note that the LEDs may be hidden behind opaque electician's tape.
  4. Replace (or add) opaque electrician's tape over the LEDs so only a fraction of their light will leak into the prism behind the LCD module from the side.
  5. Reassemble the unit, in reverse order. The brightness of the backlight should be considerably reduced, perhaps to the point where you won't be able to easily read the time in daylight; but at least you'll be able to sleep at night without eye-shades.

Thursday, 24 March 2011

RGB/HSV in HLSL 3

DDRKirby(ISQ) had problems with the HLSL code for "RGBtoHSV" in my original posting on this subject. I've had a chance to look at this in more detail and believe I know what the problem is/was. Some versions of the HLSL compiler have difficulty generating correct code for component swizzling under very specific circumstances. A minor refactoring seems to solve the problem:

float3 Hue(float H)
{
  float R = abs(H * 6 - 3) - 1;
  float G = 2 - abs(H * 6 - 2);
  float B = 2 - abs(H * 6 - 4);
  return saturate(float3(R,G,B));
}

float3 HSVtoRGB(in float3 HSV)
{
  return ((Hue(HSV.x) - 1) * HSV.y + 1) * HSV.z;
}

float3 RGBtoHSV(in float3 RGB)
{
  float3 HSV = 0;
#if NO_ASM
  HSV.z = max(RGB.r, max(RGB.g, RGB.b));
  float M = min(RGB.r, min(RGB.g, RGB.b));
  float C = HSV.z - M;
#else
  float4 RGB4 = RGB.rgbr;
  asm { max4 HSV.z, RGB4 };
  asm { max4 RGB4.w, -RGB4 };
  float C = HSV.z + RGB4.w;
#endif
  if (C != 0)
  {
    float4 RGB0 = float4(RGB, 0);
    float4 Delta = (HSV.z - RGB0) / C;
    Delta.rgb -= Delta.brg;
    Delta.rgb += float3(2,4,6);
    Delta.brg = step(HSV.z, RGB) * Delta.brg;
#if NO_ASM
    HSV.x = max(Delta.r, max(Delta.g, Delta.b));
#else
    float4 Delta4 = Delta.rgbr;
    asm { max4 HSV.x, Delta4 };
#endif
    HSV.x = frac(HSV.x / 6);
    HSV.y = 1 / Delta.w;
  }
  return HSV;
}


The major change (which produces the same optimized code as I expected from the original version) is highlighted. I'm not saying this will fix everyone's woes, but it certainly corrects the problem with the one situation I came across.