Цитата(neiver @ Feb 11 2012, 00:27)

Для этого можно использовать частичную специализацию шаблонов. Завести дополнительную шаблонный класс, вычисляющий нужную маску и сделать для него две специализации, для pin < 16 и для pin >= 16.
Спасибо за идею! В итоге так и сделал, только использовал анонимный параметр, что избавило от необходимости в вызове писать условие pin < 16.
Специализацию шаблона нельзя выполнять внутри класса, поэтому вынес наружу.
Код
namespace IO
{
template<uint32_t pin, bool = (pin < 16)>
struct ConfigurationMask
{
static inline uint32_t Clear() { return ~(0x03UL << (pin * 2)); }
static inline uint32_t SelSet(Configuration configuration) { return (((uint32_t)configuration >> 4) & 0x03UL) << (pin * 2); }
static inline uint32_t ModeSet(Configuration configuration) { return (((uint32_t)configuration >> 2) & 0x03UL) << (pin * 2); }
};
template<uint32_t pin>
struct ConfigurationMask<pin, false>
{
static inline uint32_t Clear() { return ~(0x03UL << ((pin - 16) * 2)); }
static inline uint32_t SelSet(Configuration configuration) { return (((uint32_t)configuration >> 4) & 0x03UL) << ((pin - 16) * 2); }
static inline uint32_t ModeSet(Configuration configuration) { return (((uint32_t)configuration >> 2) & 0x03UL) << ((pin - 16) * 2); }
};
template<Port port, uint32_t pin, ActiveState activestate>
class Pin
{
static_assert((pin < 32), "Pin number must be <= 31");
public:
/*
* Set Configuration
*/
static void SetConfiguration(Configuration configuration)
{
...
SEL0 &= ConfigurationMask<pin>::Clear();
SEL0 |= ConfigurationMask<pin>::SelSet(configuration);
MODE0 &= ConfigurationMask<pin>::Clear();
MODE0 |= ConfigurationMask<pin>::ModeSet(configuration);
...
}
};
}