/*!
* \file Tmeta.cpp
*
* Copyright (C) 2018 Christos Choutouridis
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*
*/
#include
#include
#include
namespace test_concepts {
using namespace utl;
/*
* Fixture like types
*/
struct Empty { };
struct HaveOnlyCopy {
HaveOnlyCopy(const HaveOnlyCopy&) = default;
HaveOnlyCopy(HaveOnlyCopy&&) = delete;
HaveOnlyCopy& operator= (const HaveOnlyCopy&) = default;
HaveOnlyCopy& operator= (HaveOnlyCopy&&) = delete;
};
struct HaveOnlyMove {
HaveOnlyMove(const HaveOnlyMove&) = delete;
HaveOnlyMove(HaveOnlyMove&&) = default;
HaveOnlyMove& operator= (const HaveOnlyMove&) = delete;
HaveOnlyMove& operator= (HaveOnlyMove&&) = default;
};
struct HaveCopyAndMove {
HaveCopyAndMove(const HaveCopyAndMove&) = default;
HaveCopyAndMove(HaveCopyAndMove&&) = default;
HaveCopyAndMove& operator= (const HaveCopyAndMove&) = default;
HaveCopyAndMove& operator= (HaveCopyAndMove&&) = default;
};
class HavePerfectForwarding {
public: template HavePerfectForwarding(T&&) { }
};
class Base { };
class Derived1 : public Base { };
class Derived2 : public Derived1 { };
class HaveOperatorBase {
public: operator Base() { return base; }
Base base;
};
struct A {
int a_;
public:
A(int a =0) : a_{a} { };
A(const A&) = default;
A(A&&) = default;
};
bool operator== (const A& l, const A& r) { return l.a_ == r.a_; }
bool operator!= (const A& l, const A& r) { return l.a_ != r.a_; }
struct B {
int b_;
public:
B(int b =0) : b_{b} { };
B(const B&) = default;
B(B&&) = default;
B& operator= (const B&) = default;
B& operator= (B&&) = default;
};
bool operator== (const B& l, const B& r) { return l.b_ == r.b_; }
bool operator!= (const B& l, const B& r) { return l.b_ != r.b_; }
bool operator< (const B& l, const B& r) { return l.b_ < r.b_; }
bool operator<= (const B& l, const B& r) { return l.b_ <= r.b_; }
bool operator> (const B& l, const B& r) { return l.b_ > r.b_; }
bool operator>= (const B& l, const B& r) { return l.b_ >= r.b_; }
TEST(TConcepts, Same) {
// Same
EXPECT_EQ (true, (Same));
EXPECT_EQ (false, (Same));
EXPECT_EQ (true, (Same));
EXPECT_EQ (true, (Same));
EXPECT_EQ (false, (Same));
EXPECT_EQ (false, (Same));
}
TEST(TConcepts, DerivedFrom) {
// DerivedFrom
EXPECT_EQ (true, (DerivedFrom));
EXPECT_EQ (true, (DerivedFrom));
EXPECT_EQ (true, (DerivedFrom));
EXPECT_EQ (false, (DerivedFrom));
EXPECT_EQ (false, (DerivedFrom));
EXPECT_EQ (false, (DerivedFrom));
}
TEST(TConcepts, ConvertibleTo) {
// ConvertibleTo
EXPECT_EQ (true, (ConvertibleTo));
EXPECT_EQ (false, (ConvertibleTo));
EXPECT_EQ (false, (ConvertibleTo));
EXPECT_EQ (true, (ConvertibleTo));
EXPECT_EQ (true, (ConvertibleTo));
EXPECT_EQ (true, (ConvertibleTo));
}
TEST(TConcepts, CommonReference) {
// CommonReference
EXPECT_EQ (true, (CommonReference));
EXPECT_EQ (true, (CommonReference));
EXPECT_EQ (true, (CommonReference));
EXPECT_EQ (false, (CommonReference));
//FIXME: CommonReference needs SFINAE friendly implementation
//EXPECT_EQ (false, (CommonReference)); <- yields compiler error
// Common
EXPECT_EQ (true, (Common));
EXPECT_EQ (true, (Common));
EXPECT_EQ (true, (Common));
EXPECT_EQ (true, (Common));
EXPECT_EQ (true, (Common));
}
TEST(TConcepts, Integral) {
// Integral
EXPECT_EQ (false, (Integral));
EXPECT_EQ (true, (Integral));
EXPECT_EQ (true, (Integral));
EXPECT_EQ (false, (Integral));
EXPECT_EQ (false, (Integral));
EXPECT_EQ (true, (Integral::value_type>));
EXPECT_EQ (false, (Integral::type>));
// SignedIntegral
EXPECT_EQ (false, (SignedIntegral));
EXPECT_EQ (true, (SignedIntegral));
EXPECT_EQ (false, (SignedIntegral));
EXPECT_EQ (false, (SignedIntegral));
EXPECT_EQ (false, (SignedIntegral));
EXPECT_EQ (false, (SignedIntegral));
EXPECT_EQ (true, (SignedIntegral::value_type>));
// UnsignedIntegral
EXPECT_EQ (false, (UnsignedIntegral));
EXPECT_EQ (true, (UnsignedIntegral));
EXPECT_EQ (false, (UnsignedIntegral));
EXPECT_EQ (false, (UnsignedIntegral));
EXPECT_EQ (false, (UnsignedIntegral));
EXPECT_EQ (true, (UnsignedIntegral::value_type>));
}
TEST(TConcepts, Assignable) {
// MoveAssignable
EXPECT_EQ (false, (MoveAssignable));
EXPECT_EQ (true, (MoveAssignable));
EXPECT_EQ (true, (MoveAssignable));
EXPECT_EQ (true, (MoveAssignable));
EXPECT_EQ (false, (MoveAssignable));
EXPECT_EQ (true, (MoveAssignable));
EXPECT_EQ (true, (MoveAssignable));
EXPECT_EQ (true, (MoveAssignable));
EXPECT_EQ (true, (MoveAssignable));
// CopyAssignable
EXPECT_EQ (false, (CopyAssignable));
EXPECT_EQ (true, (CopyAssignable));
EXPECT_EQ (true, (CopyAssignable));
EXPECT_EQ (true, (CopyAssignable));
EXPECT_EQ (true, (CopyAssignable));
EXPECT_EQ (false, (CopyAssignable));
EXPECT_EQ (true, (CopyAssignable));
EXPECT_EQ (true, (CopyAssignable));
EXPECT_EQ (true, (CopyAssignable));
// Assignable
EXPECT_EQ (false, (Assignable));
EXPECT_EQ (false, (Assignable));
EXPECT_EQ (true, (Assignable));
EXPECT_EQ (false, (Assignable));
EXPECT_EQ (false, (Assignable));
EXPECT_EQ (true, (Assignable));
EXPECT_EQ (false, (Assignable));
EXPECT_EQ (true, (Assignable));
EXPECT_EQ (true , (Assignable));
EXPECT_EQ (true, (Assignable));
}
TEST(TConcepts, Swappable) {
// Swappable, SwappableWith
EXPECT_EQ (false, (Swappable));
EXPECT_EQ (true, (Swappable));
EXPECT_EQ (true, (Swappable));
EXPECT_EQ (true, (Swappable));
EXPECT_EQ (true, (SwappableWith));
EXPECT_EQ (false, (SwappableWith));
EXPECT_EQ (false, (SwappableWith));
// Destructible
EXPECT_EQ (false, (Destructible));
EXPECT_EQ (true, (Destructible));
EXPECT_EQ (true, (Destructible));
EXPECT_EQ (true, (Destructible));
EXPECT_EQ (true, (Destructible));
EXPECT_EQ (true, (Destructible));
}
TEST(TConcepts, Constructible) {
// Constructible
EXPECT_EQ (false, (Constructible));
EXPECT_EQ (true, (Constructible));
EXPECT_EQ (true, (Constructible));
EXPECT_EQ (false, (Constructible));
EXPECT_EQ (true, (Constructible));
// DefaultConstructible
EXPECT_EQ (false, (DefaultConstructible));
EXPECT_EQ (true, (DefaultConstructible));
EXPECT_EQ (false, (DefaultConstructible));
EXPECT_EQ (true, (DefaultConstructible));
EXPECT_EQ (true, (DefaultConstructible));
EXPECT_EQ (false, (DefaultConstructible));
EXPECT_EQ (false, (DefaultConstructible));
EXPECT_EQ (false, (DefaultConstructible));
// MoveConstructible
EXPECT_EQ (false, (MoveConstructible));
EXPECT_EQ (true, (MoveConstructible));
EXPECT_EQ (true, (MoveConstructible));
EXPECT_EQ (true, (MoveConstructible));
EXPECT_EQ (true, (MoveConstructible));
EXPECT_EQ (false, (MoveConstructible));
EXPECT_EQ (true, (MoveConstructible));
EXPECT_EQ (true , (MoveConstructible));
// CopyConstructible
EXPECT_EQ (false, (CopyConstructible));
EXPECT_EQ (true, (CopyConstructible));
EXPECT_EQ (true, (CopyConstructible));
EXPECT_EQ (true, (CopyConstructible));
EXPECT_EQ (false, (CopyConstructible));
EXPECT_EQ (false, (CopyConstructible));
EXPECT_EQ (true, (CopyConstructible));
EXPECT_EQ (true , (CopyConstructible));
}
TEST(TConcepts, MovableCopyable) {
// Movable
EXPECT_EQ (false, (Movable));
EXPECT_EQ (true, (Movable));
EXPECT_EQ (true, (Movable));
EXPECT_EQ (true, (Movable));
EXPECT_EQ (true, (Movable));
EXPECT_EQ (false, (Movable));
EXPECT_EQ (true, (Movable));
EXPECT_EQ (true , (Movable));
// Copyable
EXPECT_EQ (false, (Copyable));
EXPECT_EQ (true, (Copyable));
EXPECT_EQ (true, (Copyable));
EXPECT_EQ (true, (Copyable));
EXPECT_EQ (false, (Copyable));
EXPECT_EQ (false, (Copyable));
EXPECT_EQ (true, (Copyable));
EXPECT_EQ (true , (Copyable));
}
TEST(TConcepts, Boolean) {
// Boolean
EXPECT_EQ (false, (Boolean));
EXPECT_EQ (true, (Boolean));
EXPECT_EQ (true, (Boolean));
EXPECT_EQ (true, (Boolean));
EXPECT_EQ (true, (Boolean));
EXPECT_EQ (true, (Boolean));
EXPECT_EQ (false, (Boolean));
}
TEST(TConcepts, Comparable) {
// EqualityComparable
EXPECT_EQ (false, (EqualityComparable));
EXPECT_EQ (true, (EqualityComparable));
EXPECT_EQ (true, (EqualityComparable));
EXPECT_EQ (false, (EqualityComparable));
EXPECT_EQ (true, (EqualityComparable));
// EqualityComparableWith
EXPECT_EQ (false, (EqualityComparableWith));
EXPECT_EQ (false, (EqualityComparableWith));
EXPECT_EQ (true, (EqualityComparableWith));
EXPECT_EQ (true, (EqualityComparableWith));
EXPECT_EQ (true, (EqualityComparableWith));
EXPECT_EQ (false, (EqualityComparableWith));
EXPECT_EQ (false, (EqualityComparableWith));
EXPECT_EQ (true, (EqualityComparableWith));
EXPECT_EQ (false, (EqualityComparableWith));
// StrictTotallyOrdered
EXPECT_EQ (false, (StrictTotallyOrdered));
EXPECT_EQ (true, (StrictTotallyOrdered));
EXPECT_EQ (true, (StrictTotallyOrdered));
EXPECT_EQ (true, (StrictTotallyOrdered));
EXPECT_EQ (false, (StrictTotallyOrdered));
EXPECT_EQ (false, (StrictTotallyOrdered));
EXPECT_EQ (true, (StrictTotallyOrdered));
// StrictTotallyOrderedWith
EXPECT_EQ (false, (StrictTotallyOrderedWith));
EXPECT_EQ (false, (StrictTotallyOrderedWith));
EXPECT_EQ (true, (StrictTotallyOrderedWith));
EXPECT_EQ (true, (StrictTotallyOrderedWith));
EXPECT_EQ (false, (StrictTotallyOrderedWith));
EXPECT_EQ (false, (StrictTotallyOrderedWith));
EXPECT_EQ (false, (StrictTotallyOrderedWith));
EXPECT_EQ (true, (StrictTotallyOrderedWith));
EXPECT_EQ (false, (StrictTotallyOrderedWith));
}
TEST(TConcepts, Types) {
// Semiregular
EXPECT_EQ (false, (Semiregular));
EXPECT_EQ (true, (Semiregular));
EXPECT_EQ (true, (Semiregular));
EXPECT_EQ (false, (Semiregular));
EXPECT_EQ (false, (Semiregular));
EXPECT_EQ (false, (Semiregular));
EXPECT_EQ (false, (Semiregular));
EXPECT_EQ (true, (Semiregular));
// Regular
EXPECT_EQ (false, (Regular));
EXPECT_EQ (true, (Regular));
EXPECT_EQ (true, (Regular));
EXPECT_EQ (false, (Regular));
EXPECT_EQ (false, (Regular));
EXPECT_EQ (false, (Regular));
EXPECT_EQ (false, (Regular));
EXPECT_EQ (false, (Regular));
EXPECT_EQ (true, (Regular));
// Scalar
EXPECT_EQ (false, (Scalar));
EXPECT_EQ (true, (Scalar));
EXPECT_EQ (true, (Scalar));
EXPECT_EQ (false, (Scalar));
EXPECT_EQ (false, (Scalar));
// Arithmetic
EXPECT_EQ (false, (Arithmetic));
EXPECT_EQ (true, (Arithmetic));
EXPECT_EQ (false, (Arithmetic));
EXPECT_EQ (false, (Arithmetic));
EXPECT_EQ (false, (Arithmetic));
// FloatingPoint
EXPECT_EQ (false, (FloatingPoint));
EXPECT_EQ (true, (FloatingPoint));
EXPECT_EQ (true, (FloatingPoint));
EXPECT_EQ (false, (FloatingPoint));
EXPECT_EQ (false, (FloatingPoint));
EXPECT_EQ (false, (FloatingPoint));
EXPECT_EQ (false, (FloatingPoint));
}
struct Inv {
void operator() (int) { };
void operator() () { };
};
struct Pred {
bool operator () (int) { return true; }
bool operator () (int, int) { return true; }
};
TEST(TConcepts, Callable) {
EXPECT_EQ (true, (Invocable));
EXPECT_EQ (true, (Invocable));
EXPECT_EQ (true, (Invocable));
EXPECT_EQ (false, (Invocable));
EXPECT_EQ (true, (RegularInvocable));
EXPECT_EQ (false, (Predicate));
EXPECT_EQ (true, (Predicate));
EXPECT_EQ (false, (Predicate));
EXPECT_EQ (true, (Relation));
EXPECT_EQ (true, (Relation));
EXPECT_EQ (false, (Relation));
EXPECT_EQ (true, (StrictWeakOrder));
EXPECT_EQ (false, (StrictWeakOrder));
}
struct Incr {
Incr& operator++() { return *this; }
Incr operator++(int) { return *this; }
};
int type_printer (int* i) { return *i; }
TEST(TConcepts, Iterators) {
// type_printer(detail::try_ppI{});
// type_printer(detail::try_Ipp{});
// type_printer(meta::detected_t{});
EXPECT_EQ (true, (WeaklyIncrementable));
EXPECT_EQ (false, (WeaklyIncrementable));
EXPECT_EQ (false, (WeaklyIncrementable));
EXPECT_EQ (true, (WeaklyIncrementable));
EXPECT_EQ (false, (WeaklyIncrementable));
}
}