В продолжении заметки о деревьях типов реализуем обратный алгоритм (поиск типа по номеру в дереве).
Для начала опишу вспомогательные структуры, которые потребуются позже:
Алгоритм поиска типа по его номеру в дереве aDFS будет выдавать подходящий тип, если вершина с искомым номером есть в дереве, иначе NullType. Вот его реализация:
И наш любимый пример будет выглядеть так:
В консоли будет напечатаны 1 и 0.
Для начала опишу вспомогательные структуры, которые потребуются позже:
// Тип Null, обозначающий пустой ответ
class NullType;
// Проверка типа на равенство NullType
template <class T>
struct isNull
{
enum { value = false };
};
template <>
struct isNull<NullType>
{
enum { value = true };
};
// структура Select, описанная у Александреску
template<bool flag, class T, class U>
struct Select
{
typedef T Result;
};
template<class T, class U>
struct Select<false, T, U>
{
typedef U Result;
};
Алгоритм поиска типа по его номеру в дереве aDFS будет выдавать подходящий тип, если вершина с искомым номером есть в дереве, иначе NullType. Вот его реализация:
template <class TTree, unsigned int n, unsigned int i> struct aDFS_;
// Лист с подходящим номером
template <class T, unsigned int n>
struct aDFS_<T, n, n>
{
typedef T Result;
};
// Лист с неподходящим номером
template <class T, unsigned int n, unsigned int i>
struct aDFS_
{
typedef NullType Result;
};
// Развилка с подходящим номером
template <class Left, class Right, unsigned int n>
struct aDFS_<TypeTree<Left, Right>, n, n>
{
typedef TypeTree<Left, Right> Result;
};
// Развилка с неподходящим номером
template <class Left, class Right, unsigned int n, unsigned int i>
struct aDFS_<TypeTree<Left, Right>, n, i>
{
private:
typedef typename aDFS_<Left, n, 2*i>::Result Res1;
typedef typename aDFS_<Right, n, 2*i + 1>::Result Res2;
public:
typedef typename Select<isNull<Res2>::value, Res1, Res2>::Result Result;
};
// TTree - дерево типов, n - номер искомой вершины
template <class TTree, unsigned int n>
struct aDFS
{
typedef typename aDFS_<TTree, n, 1>::Result Result;
};
И наш любимый пример будет выглядеть так:
typedef
TypeTree<TypeTree<int, double>, TypeTree<float, TypeTree<char, long> > >
TestTree;
std::cout << isNull<aDFS<TestTree, 14>::Result>::value << std::endl;
std::cout << isNull<aDFS<TestTree, 144>::Result>::value << std::endl;
В консоли будет напечатаны 1 и 0.
Комментариев нет:
Отправить комментарий