|
// preprocessor.h
// This file is an extract from some files (like ct_if.hpp) of the huge Boost library (35 Megabyte)
// modified, shortened and compacted to one file by ElmueSoft (www.elmue.de.vu or kickme.to/elmue)
// -------------------------------------------------------------------
// Boost.Function library
// Copyright (C) 2001-2003 Doug Gregor (gregod@cs.rpi.edu)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
// For more information, see http://www.boost.org
// -------------------------------------------------------------------
#if !defined(PREPROCESSOR_H)
#define PREPROCESSOR_H
// turn off MS Visual Studio warning: "Identifier was truncated to '255' characters in the debug information"
#pragma warning( disable : 4786 )
// Note:
// Older versions of compilers do not support partial template specialization
// In this case a workaround is necessary
#if _MSC_VER == 1200 // Visual Studio 6.0
#define PARTIAL_TEMPLATE_SPECIALIZATION_AVAILABLE 0
#elif _MSC_VER == 1300 // Visual Studio 7.0 (.NET)
#define PARTIAL_TEMPLATE_SPECIALIZATION_AVAILABLE 0
#elif _MSC_VER == 1310 // Visual Studio 7.1 (.NET 2003)
#define PARTIAL_TEMPLATE_SPECIALIZATION_AVAILABLE 1
#else // Unknown Compiler (please set the value manually to 0 or 1)
#error Unknown compiler : insert 0 or 1 in the next line and comment out this line !
#define PARTIAL_TEMPLATE_SPECIALIZATION_AVAILABLE ?
#endif
// *********** <PREPROCESSOR MACROS> ***************
// UNUSABLE is used as a dummy replacement for functions returning void
// Needed for compilers not supporting partial template specialization
// (like MS Visual Studio 6)
#define UNUSABLE \
cPreProcessor::unusable*
// IS_VOID returns true if class T == void, otherwise false
#define IS_VOID(T) \
cPreProcessor::is_void<T>::value
// IS_USABLE returns 0 if class T == cPreProcessor::unusable*, otherwise 1
#define IS_USABLE(T) \
cPreProcessor::is_usable<T>::value
// CLASS_SWITCH returns class A if condition == true, class B if condition == false
#define CLASS_SWITCH(condition, A, B) \
cPreProcessor::select_switch<condition, A, B>::value
// *********** <PREPROCESSOR SWITCHES> ***************
struct cPreProcessor
{
// ################ unusable #################
struct unusable
{
// empty structure
};
// ################ is_void #################
template <typename T>
struct is_void
{ enum { value = false }; };
// Specialization of is_void for T == void
template <>
struct is_void<void>
{ enum { value = true }; };
// ################ is_usable #################
template <typename T>
struct is_usable
{ enum { value = 1 }; };
// Specialization of is_usable for T == unusable*
template <>
struct is_usable<unusable*>
{ enum { value = 0 }; };
// ################ select_switch #################
#if PARTIAL_TEMPLATE_SPECIALIZATION_AVAILABLE
// for newer compilers (e.g. Visual Studio 7.1 = Visual Studio .NET 2003)
template<int condition, class A, class B>
// partial specialization for condition == illegal value
struct select_switch
{
typedef typename UNUSABLE value;
};
// partial specialization for condition == true
template<class A, class B>
struct select_switch<true, A, B>
{
typedef typename A value;
};
// partial specialization for condition == false
template<class A, class B>
struct select_switch<false, A, B>
{
typedef typename B value;
};
#else // !PARTIAL_TEMPLATE_SPECIALIZATION_AVAILABLE
// for older compilers: (e.g. Visual Studio 6.0 and 7.0)
// the following has to be that awkward because lots of old compilers
// do not support partial template specialization
struct switch_true
{
template<class A, class B>
struct class_switch
{ typedef A ret_class; };
};
struct switch_false
{
template<class A, class B>
struct class_switch
{ typedef B ret_class; };
};
template<int condition>
struct condition_switch
{ typedef switch_true selector; };
// Specialization of condition_switch for condition == false
template <>
struct condition_switch<false>
{ typedef switch_false selector; };
template<int condition, class A, class B>
struct select_switch
{
typedef condition_switch<condition>::selector Selector;
typedef Selector::class_switch<A, B>::ret_class value;
};
#endif // PARTIAL_TEMPLATE_SPECIALIZATION_AVAILABLE
};
#endif // PREPROCESSOR_H
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.