integer_concept.h

Back to Integers

pastel/sys/integer/

// Description: Integer concept
// Documentation: integers.txt

#ifndef PASTELSYS_INTEGER_CONCEPT_H
#define PASTELSYS_INTEGER_CONCEPT_H

#include "pastel/sys/mytypes.h"
#include "pastel/sys/algebra/ordered_ring_concept.h"
#include "pastel/sys/real/scientific_notation_fwd.h"
#include "pastel/sys/printable/printable_concept.h"

// See concept.txt for why native types must be 
// defined _before_ the concept.
#include "pastel/sys/integer/native_integer.h"

namespace Pastel 
{

    //! An integer.
    template <typename T>
    concept Integer_Concept_ = 
        Ordered_Ring_Concept<T> &&
        Printable_Concept<T> && 
        requires(T t) {
        //! Constructs with zero.
        T();
        // Constructs with a native integer.
        T(true);
        T((int8)0);
        T((uint8)0);
        T((int16)0);
        T((uint16)0);
        T((int32)0);
        T((uint32)0);
        T((int64)0);
        T((uint64)0);
        // Swaps with another integer.
        //swap(t, t);
        //! Computes roundTowardsZero(t / u).
        {t /= t} -> std::convertible_to<T>;
        {t / t} -> std::convertible_to<T>;
        //! Remainder of t when divided by u.
        /*!
       It holds that t = (t / u) * u + (t % u).
       Note that the remainder can be negative.
       */
        {t %= t} -> std::convertible_to<T>;
        {t % t} -> std::convertible_to<T>;
        //! Bitwise logical and.
        {t &= t} -> std::convertible_to<T>;
        {t & t} -> std::convertible_to<T>;
        //! Bitwise logical or.
        {t |= t} -> std::convertible_to<T>;
        {t | t} -> std::convertible_to<T>;
        //! Bitwise logical xor.
        {t ^= t} -> std::convertible_to<T>;
        {t ^ t} -> std::convertible_to<T>;
        //! Computes t * 2^n.
        {t <<= (integer)0} -> std::convertible_to<T>;
        {t << (integer)0} -> std::convertible_to<T>;
        //! Computes floor(t / 2^n).
        {t >>= (integer)0} -> std::convertible_to<T>;
        {t >> (integer)0} -> std::convertible_to<T>;
        //! Returns whether 'that' is even.
        {even(t)} -> std::convertible_to<bool>;
        //! Returns whether 'that' is odd.
        {odd(t)} -> std::convertible_to<bool>;
        //! Returns an integer with maximum positive value.
        {Infinity()} -> std::convertible_to<T>;
        //! Returns the number in scientific notation.
        {asScientific(t)} -> std::convertible_to<ScientificNotation>;
    };

    template <typename T>
    concept Integer_Concept = 
        Integer_Concept_<RemoveCvRef<T>>;

    using Integer_Archetype = integer;

}

#endif