I have a template class for a video driver. The driver supports multiple screen modes, including a black and white mode and a 7-color mode. Using dithering it can also do grayscale or a virtual set of colors at the bit depth the user defines.
Unfortunately, the way my code is orchestrated, each different screen mode requires the instantiation of a different concrete type, because different color/pixel formats yield different concrete types.
I have a
mode<>()
template function off the driver which allows you to select the screen mode to use. Upon calling it, the screen mode must change, and the in memory frame buffer be reallocated.
Therefore, any nested template instantiation needs access to the parent driver instantiation, so that it can fiddle with a static variable for the current screen mode, and also deallocate the previous screen mode.
because of this, I had the screen modes nested under the driver template class but alas I cannot specialize them at that scope - at least with C++14 which is what I have to target)
the other option would be to use
friend
but how in the heck do I friend a template? I don't know if it's doable - I've never done it before.
I can't use a non-template static because I need that static mode variable to be tied to the particular instantiation of a concrete driver type, just in case you happen to be driving multiple of the same screen on different pins. That's not a typical case for this particular screen, but all of my other drivers work this way, so I really don't want to make this the exception unless I have no other choice.
What I have tried:
I tried specializing template structs from inside a class, but the compiler won't let me do that.
Right now the code looks like this:
#pragma once
#include <Arduino.h>
#include <gfx_bitmap.hpp>
namespace arduino {
template<int8_t PinDC,
int8_t PinRst,
int8_t PinWait,
typename Bus,
unsigned int WriteSpeedPercent = 200,
unsigned int ReadSpeedPercent = WriteSpeedPercent>
struct waveshare5in65 final {
template<uint8_t BitDepth,bool Color> struct screen_mode final {
static_assert(Color==false || (BitDepth>=4),"Color modes must have a bit depth of at least 4");
};
template<uint8_t BitDepth,bool Color> screen_mode<BitDepth,Color> mode() {
}
};
}