/*! * \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)); } }