/* UTIL.hpp - metaprogramming helpers and utilities Copyright (C) Lumiera.org 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef LUMIERA_META_UTIL_H #define LUMIERA_META_UTIL_H namespace lumiera { namespace typelist { /* types for figuring out the overload resolution chosen by the compiler */ typedef char Yes_t; struct No_t { char padding[8]; }; /** semi-automatic detection if an instantiation is possible. * Requires help by the template to be tested, which needs to define * a typedef member \c is_defined. The embedded metafunction Test can be used * as a predicate for filtering types which may yield a valid instantiation * of the candidate template in question. * \par * A fully automated solution for this problem is impossible by theoretic reasons. * Any non trivial use of such a \c is_defined trait would break the "One Definition Rule", * as the state of any type can change from "partially defined" to "fully defined" over * the course of any translation unit. Thus, even if there may be a \em solution out there, * we can expect it to break at some point by improvements/fixes to the C++ Language. */ template class _CandidateTemplate_> struct Instantiation { template class Test { typedef _CandidateTemplate_ Instance; template static Yes_t check(typename U::is_defined *); template static No_t check(...); public: static const bool value = (sizeof(Yes_t)==sizeof(check(0))); }; }; } // namespace typelist } // namespace lumiera #endif