/*
Copyright (C) 2013 Tom Bachmann
This file is part of FLINT.
FLINT is free software: you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License (LGPL) as published
by the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version. See .
*/
#ifndef CXX_MP_H
#define CXX_MP_H
namespace flint {
namespace mp {
/////////////////////////////////
// BASIC METAPROGRAMMING HELPERS
/////////////////////////////////
// Most of these helpers *compute* something. In this case, they have a static
// static const member "val" storing the result of the computation. The
// arguments of the computation are template parameters, and are usually *not*
// PODs, but instead themselves types with a static constant "val" member.
// See value_of, true_ and false_ for how to pass in explicit values to your
// computation.
// Wrap the boolean value "v" into the static const member "val".
template struct value_of { static const bool val = v; };
// Boolean inputs for computations.
struct true_ : value_of { };
struct false_ : value_of { };
// Compute if two input *types* (not values!) are equal.
template
struct equal_types : false_ { };
template
struct equal_types : true_ { };
// Compute logical negation of the input value.
template
struct not_ : value_of { };
// Compute logical and of the input values.
template
struct and_ : and_ > { };
template
struct and_ : value_of { };
template
struct and_v : and_ > { };
// Compute logical or of the input values.
template
struct or_ : or_ > { };
template
struct or_ : value_of { };
// Compute V1 or V2, depending on C
template
struct if_v {typedef V1 type;};
template
struct if_v {typedef V2 type;};
template
struct if_ : if_v { };
// Choose a value depending on a sequence of conditions.
// This has he same meaning as
// int select(bool c1 = false, bool c2 = false, bool c3 = false)
// {
// if(c1)
// return v1;
// if(c2)
// return v2;
// if(c3)
// return v3;
// return d;
// }
template
struct select : if_::type> { };
template
struct select {typedef D type;};
// Conditional template enabling helper. (See below for explanation.)
template
struct enable_if_v
{
typedef U type;
static const int val = 0;
};
template
struct enable_if_v { };
// Conditional template enabling.
//
// These two helpers (enable_if and disable_if) can be used wherever the
// SFINAE rule applies to conditionally enable or disable template
// specialisations.
//
// If T evaluaties to true, then enable_if has a member typedef "type", which
// is the parameter U, and also a static const int member val (of zero).
// If on the other hand T evaluates to false, then enable_if is empty.
// The meaning of T is reversed for disable_if.
// See e.g. [0] or the tests for how to use this.
//
// [0] https://www.boost.org/doc/libs/1_53_0/libs/utility/enable_if.html
//
template
struct enable_if : public enable_if_v { };
template
struct disable_if : public enable_if, U> { };
struct empty { };
} // mp
} // flint
#endif