/* Copyright (C) 2015 * swift project Community / Contributors * * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, * including this file, may be copied, modified, propagated, or distributed except according to the terms * contained in the LICENSE file. */ //! \file #ifndef BLACKMISC_INHERITANCE_TRAITS_H #define BLACKMISC_INHERITANCE_TRAITS_H #include #include namespace BlackMisc { class CEmpty; /*! * If T has a member typedef base_type, this trait will obtain it, otherwise void. */ template class BaseOf { //template static typename U::base_type *test(int); template static typename U::base_type *test(typename std::enable_if::value, int>::type); template static void *test(...); public: //! The declared base_type of T, or void if there is none. typedef typename std::remove_pointer(0))>::type type; }; /*! * It T has a member typedef base_type which is a registered metatype, this trait will obtain it, otherwise void. */ template class MetaBaseOf { public: //! Type of T::base_type, or void if not declared. typedef typename std::conditional::type>::Defined, typename BaseOf::type, void>::type type; }; /*! * If T has a member typedef base_type which has a member propertyByIndex, this trait will obtain it, otherwise void. */ template class IndexBaseOf { // http://en.wikibooks.org/wiki/More_C++_Idioms/Member_Detector struct Empty {}; struct Fallback { int propertyByIndex; }; template struct int_t { typedef int type; }; template struct Derived : public Fallback, public std::conditional::value, Empty, U>::type {}; template static void test(typename int_t<&Derived::propertyByIndex>::type); template static U test(...); public: //! Type of T::base_type, or void if not declared. typedef decltype(test::type>(0)) type; }; /*! * Alias for typename BaseOf::type. */ template using BaseOfT = typename BaseOf::type; /*! * Alias for typename MetaBaseOf::type. */ template using MetaBaseOfT = typename MetaBaseOf::type; /*! * Alias for typename IndexBaseOf::type. */ template using IndexBaseOfT = typename IndexBaseOf::type; } #endif