Click here to Skip to main content
15,886,823 members
Articles / Programming Languages / C++

Type-safe Callbacks in C++

Rate me:
Please Sign up or sign in to vote.
4.71/5 (47 votes)
13 Feb 2008CPOL8 min read 203.3K   4.9K   130  
Demonstrates how to use type-safe callbacks in C++
// preprocessor.h

// This file is an extract from the huge Boost library (35 Megabyte)
// modified, shortened and compacted to one file by ElmueSoft (www.elmue.de.vu)



// -------------------------------------------------------------------
// 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


// *********** <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
{
    struct unusable
    {
        // empty structure
    };

    // ----------------------

    template <typename T>
    struct is_void
    { enum { value = false }; };

    // Specialization of is_void for T == void
    template <>
    struct is_void<void>
    { enum { value = true }; };

    // ----------------------

    template <typename T>
    struct is_usable
    { enum { value = 1 }; };

    // Specialization of is_usable for T == unusable*
    template <>
    struct is_usable<unusable*>
    { enum { value = 0 }; };

    // ----------------------

    // the following is that awkward because Visual Studio 6
    // does 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 // 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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) ElmüSoft
Chile Chile
Software Engineer since 40 years.

Comments and Discussions