|
- /*!
- * \file TmetaDetection.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 <http://www.gnu.org/licenses/>.
- *
- */
- #include <utl/meta/meta.h>
- #include <gtest/gtest.h>
- #include <type_traits>
-
- namespace TmetaDetection {
- using namespace utl;
- using namespace meta;
-
- /*
- * Types to behave like Fixtures
- */
- struct Foo {};
- struct Bar {};
-
- template <typename T> struct A {
- using type = T; // nested type
- A(int i, double d) : i_(i), d_(d) {} // declare a non-trivial constructor
- A& operator++() { ++i_; return *this; } // declare an operator
-
- // A sfinae function
- template <typename TT = T, typename = when<std::is_integral<TT>::type::value>>
- TT sfun () { return TT{}; }
- private:
- int i_; double d_;
- };
-
- // A binary metafunction
- template <typename T1, typename T2>
- struct mFun {
- using type = std::is_same <T1, T2>;
- };
-
- // detectors
- template <typename T> using try_type = typename T::type;
- template <typename T> using try_none = typename T::none;
- template <typename T> using try_ctor1= decltype (T(std::declval<int>(), std::declval<double>()));
- template <typename T> using try_ctor2= decltype (T(std::declval<int>()));
- template <typename T> using try_ppT = decltype (++(std::declval<T>()));
- template <typename T> using try_Tpp = decltype (std::declval<T>()++);
- template <typename T> using try_sfun = decltype (std::declval<T>().sfun());
-
- /*
- * void_t
- */
- TEST(TmetaDetection, VoidType) {
- EXPECT_EQ(true, (std::is_same<void, void_t<int, long, void*, void, Foo, Bar>>()));
- EXPECT_EQ(true, (std::is_same<void, void_t<>>()));
- }
-
- /*
- * not a type
- */
- TEST(TmetaDetection, NotAType) {
- EXPECT_EQ(false, (std::is_default_constructible<nat_>()));
- EXPECT_EQ(false, (std::is_destructible<nat_>()));
- EXPECT_EQ(false, (std::is_copy_constructible<nat_>()));
- EXPECT_EQ(false, (std::is_copy_assignable<nat_>()));
- }
-
- /*
- * Idiom
- */
- TEST(TmetaDetection, IsDetected) {
-
- EXPECT_EQ (true, (std::is_same< true_, is_detected<try_type, A<int>> >()));
- EXPECT_EQ (true, (std::is_same< false_, is_detected<try_none, A<int>> >()));
- EXPECT_EQ (true, (std::is_same< true_, is_detected<try_ctor1, A<int>> >()));
- EXPECT_EQ (true, (std::is_same< false_, is_detected<try_ctor2, A<int>> >()));
- EXPECT_EQ (true, (std::is_same< true_, is_detected<try_ppT, A<int>> >()));
- EXPECT_EQ (true, (std::is_same< false_, is_detected<try_Tpp, A<int>> >()));
- EXPECT_EQ (true, (std::is_same< true_, is_detected<try_sfun, A<int>> >()));
- EXPECT_EQ (true, (std::is_same< false_, is_detected<try_sfun, A<double>> >()));
-
- EXPECT_EQ (true, (std::is_same< true_, is_detected<mFun, int, void> >()));
- EXPECT_EQ (true, (std::is_same< false_, is_detected<mFun, char> >()));
- EXPECT_EQ (true, (std::is_same< false_, is_detected<mFun, char, void, void> >()));
-
- EXPECT_EQ (true, (is_detected_v<try_type, A<int>>));
- EXPECT_EQ (false,(is_detected_v<try_none, A<int>>));
- EXPECT_EQ (true, (is_detected_v<mFun, int, void>));
-
- }
-
- /*
- * Idiom
- */
- TEST(TmetaDetection, Toolkit) {
-
- // detected_t
- EXPECT_EQ (true, (std::is_same< int, detected_t<try_type, A<int>> >()));
- EXPECT_EQ (true, (std::is_same< nat_, detected_t< try_none, A<int>> >()));
- EXPECT_EQ (true, (std::is_same< A<int>, detected_t< try_ctor1, A<int>> >()));
- EXPECT_EQ (true, (std::is_same< nat_, detected_t< try_ctor2, A<int>> >()));
- EXPECT_EQ (true, (std::is_same< A<int>&,detected_t< try_ppT, A<int>> >()));
- EXPECT_EQ (true, (std::is_same< nat_, detected_t< try_Tpp, A<int>> >()));
- EXPECT_EQ (true, (std::is_same< int, detected_t< try_sfun, A<int>> >()));
- EXPECT_EQ (true, (std::is_same< nat_, detected_t< try_sfun, A<double>> >()));
-
- EXPECT_EQ (true, (std::is_same< nat_, detected_t<mFun, void> >()));
- EXPECT_EQ (true, (std::is_same< mFun<int, int>,
- detected_t<mFun, int, int> >()));
-
- // detected_or_t
- EXPECT_EQ (true, (std::is_same< int, detected_or_t<Foo, try_type, A<int>> >()));
- EXPECT_EQ (true, (std::is_same< Foo, detected_or_t<Foo, try_none, A<int>> >()));
- EXPECT_EQ (true, (std::is_same< A<int>, detected_or_t<void, try_ctor1, A<int>> >()));
- EXPECT_EQ (true, (std::is_same< void, detected_or_t<void, try_ctor2, A<int>> >()));
- EXPECT_EQ (true, (std::is_same< A<int>&,detected_or_t<nil_, try_ppT, A<int>> >()));
- EXPECT_EQ (true, (std::is_same< nil_, detected_or_t<nil_, try_Tpp, A<int>> >()));
- EXPECT_EQ (true, (std::is_same< int, detected_or_t<void*, try_sfun, A<int>> >()));
- EXPECT_EQ (true, (std::is_same< void*, detected_or_t<void*, try_sfun, A<double>> >()));
-
- EXPECT_EQ (true, (std::is_same< nil_, detected_or_t<nil_, mFun, int> >()));
- EXPECT_EQ (true, (std::is_same< mFun<char, int>,
- detected_or_t<void, mFun, char, int> >()));
-
- // is_detected_exact
- EXPECT_EQ (true, (std::is_same<true_, is_detected_exact< int, try_type, A<int>> >()));
- EXPECT_EQ (true, (std::is_same<false_, is_detected_exact< int, try_none, A<int>> >()));
- EXPECT_EQ (true, (std::is_same<true_, is_detected_exact< A<int>, try_ctor1, A<int>> >()));
- EXPECT_EQ (true, (std::is_same<false_, is_detected_exact< A<int>, try_ctor2, A<int>> >()));
- EXPECT_EQ (true, (std::is_same<true_, is_detected_exact< A<int>&,try_ppT, A<int>> >()));
- EXPECT_EQ (true, (std::is_same<false_, is_detected_exact< A<int>&,try_Tpp, A<int>> >()));
- EXPECT_EQ (true, (std::is_same<true_, is_detected_exact< int, try_sfun, A<int>> >()));
- EXPECT_EQ (true, (std::is_same<false_, is_detected_exact< int, try_sfun, A<double>> >()));
-
- EXPECT_EQ (true, (std::is_same<true_, is_detected_exact<mFun<char, int>, mFun, char, int> >()));
- EXPECT_EQ (true, (std::is_same<false_, is_detected_exact<mFun<int, int>, mFun, int> >())); // it would be better to check against mFun<int>
-
- EXPECT_EQ (true, (is_detected_exact_v< int, try_type, A<int>> ));
- EXPECT_EQ (false,(is_detected_exact_v< int, try_none, A<int>> ));
-
- // is_detected_convertible
- EXPECT_EQ (true, (std::is_same<true_, is_detected_convertible< int, try_type, A<char>> >()));
- EXPECT_EQ (true, (std::is_same<false_, is_detected_convertible< int, try_none, A<int>> >()));
- EXPECT_EQ (true, (std::is_same<false_, is_detected_convertible< mFun<int, int>, mFun, char, int> >()));
-
- EXPECT_EQ (true, (is_detected_convertible_v< int, try_type, A<char>> ));
- EXPECT_EQ (false,(is_detected_convertible_v< int, try_none, A<int>> ));
-
- }
- }
|