TooN 2.1
internal/introspection.hh
00001 // -*- c++ -*-
00002 
00003 // Copyright (C) 2012
00004 // Ed Rosten (er258@cam.ac.uk)
00005 //
00006 // This file is part of the TooN Library.  This library is free
00007 // software; you can redistribute it and/or modify it under the
00008 // terms of the GNU General Public License as published by the
00009 // Free Software Foundation; either version 2, or (at your option)
00010 // any later version.
00011 
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 
00017 // You should have received a copy of the GNU General Public License along
00018 // with this library; see the file COPYING.  If not, write to the Free
00019 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00020 // USA.
00021 
00022 // As a special exception, you may use this file as part of a free software
00023 // library without restriction.  Specifically, if other files instantiate
00024 // templates or use macros or inline functions from this file, or you compile
00025 // this file and link it with other files to produce an executable, this
00026 // file does not by itself cause the resulting executable to be covered by
00027 // the GNU General Public License.  This exception does not however
00028 // invalidate any other reasons why the executable file might be covered by
00029 // the GNU General Public License.
00030 
00031 // Allocators always copy data on copy construction.
00032 //
00033 // When a Vector/Matrix is constructed from a different, but compatible type
00034 // copying is done at a much higher level: above the level that knows how the
00035 // data is laid out in memory.
00036 //
00037 // At this level, copy construction is required since it is only known here 
00038 // whether data or a reference to data should be copied.
00039 
00040 
00041 ///Pretty generic SFINAE introspection generator
00042 ///@ingroup gInternal
00043 namespace TooN{
00044 namespace Internal{
00045 //Fake function to pretend to return an instance of a type
00046 template<class C>
00047 const C& get();
00048 
00049 //Two typedefs guaranteed to have different sizes
00050 typedef char OneSized[1];
00051 typedef char TwoSized[2];
00052 
00053 
00054 //Class to give us a size 2 return value or fail on 
00055 //substituting S
00056 template<int S> 
00057 struct SFINAE_dummy
00058 {
00059         typedef TwoSized Type;
00060 };
00061 
00062 
00063 #define TOON_CREATE_THING_DETECTOR(Y, X, Z) \
00064 template<class C>\
00065 struct Has_##X##_##Z\
00066 {\
00067         static OneSized& detect_##X##_##Z(...);\
00068 \
00069         template<class S>\
00070         static typename SFINAE_dummy<sizeof(Y)>::Type& detect_##X##_##Z(const S&);\
00071 \
00072         static const bool Has = sizeof(detect_##X##_##Z(get<C>())) == 2;\
00073 }
00074 
00075 #define TOON_CREATE_MEMBER_DETECTOR(X)  TOON_CREATE_THING_DETECTOR(S::X, X, Member)
00076 #define TOON_CREATE_METHOD_DETECTOR(X)  TOON_CREATE_THING_DETECTOR(&S::X, X, Method)
00077 #define TOON_CREATE_TYPEDEF_DETECTOR(X) TOON_CREATE_THING_DETECTOR(typename S::X, X, Typedef)
00078 
00079 }}