detecting basic types

Discussion in 'C++' started by Lasse Skyum, Dec 22, 2003.

  1. Lasse Skyum

    Lasse Skyum Guest

    Hi All,

    Is it possible to detect (at compile-time) if an item is a basic type (int,
    float, double,...) or an instance of a class/struct?

    I'm thinking something like: (obviosly this isn't working...)

    template<typename T>
    CMyFileClass::Serialize(T &x)
    {
    #if IS_BASIC_TYPE(T)
    // handle basic type
    #else
    // handle a class inherited from my CSerializable class
    #endif
    }


    BTW, I'm writing serialization of data for a gameproject....

    Thanks for any help!
    Lasse
    Lasse Skyum, Dec 22, 2003
    #1
    1. Advertising

  2. "Lasse Skyum" <no spam> wrote in message
    news:3fe7677f$0$27363$...
    > Hi All,
    >
    > Is it possible to detect (at compile-time) if an item is a basic type

    (int,
    > float, double,...) or an instance of a class/struct?


    Andrei Alexandrescu is adressing this issue in his book "Modern C++ design",
    see section 2.10.2 "Detection of Fundamental Types".

    Thierry
    Thierry Miceli, Dec 22, 2003
    #2
    1. Advertising

  3. In article <3fe7677f$0$27363$>,
    "Lasse Skyum" <no spam> wrote:

    > Hi All,
    >
    > Is it possible to detect (at compile-time) if an item is a basic type (int,
    > float, double,...) or an instance of a class/struct?
    >
    > I'm thinking something like: (obviosly this isn't working...)
    >
    > template<typename T>
    > CMyFileClass::Serialize(T &x)
    > {
    > #if IS_BASIC_TYPE(T)
    > // handle basic type
    > #else
    > // handle a class inherited from my CSerializable class
    > #endif
    > }


    You might be interested in the type traits library at boost:

    http://www.boost.org/libs/type_traits/index.htm

    This library has been submitted for standardization and accepted into
    the first library technical report:

    http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1424.htm

    A close facsimile of this lib has shipped with Metrowerks CodeWarrior
    for the past 3 years. It lives in namespace Metrowerks in the header
    <msl_utility>.

    These libs might be used like:

    #include <msl_utility>

    using namespace Metrowerks;

    struct CSerializable {};

    template <class T>
    struct CMyFileClass
    {
    void Serialize(T& x);
    private:
    void Serialize(T& x, int2type<false>);
    void Serialize(T& x, int2type<true>);
    };

    template<typename T>
    inline
    void
    CMyFileClass<T>::Serialize(T &x)
    {
    Serialize(x, int2type<is_arithmetic<T>::value>());
    }

    template<typename T>
    void
    CMyFileClass<T>::Serialize(T &x, int2type<true>)
    {
    // handle basic type
    }

    template<typename T>
    void
    CMyFileClass<T>::Serialize(T &x, int2type<false>)
    {
    compile_assert<is_convertible<T, CSerializable>::value>
    must_be_convertible_to_CSerializable;
    // handle a class inherited from my CSerializable class
    }

    I wrote this using the Metrowerks tools so that I could check it before
    I posted. The boost or std::tr1 interface would be very close.

    -Howard
    Howard Hinnant, Dec 22, 2003
    #3
  4. Lasse Skyum

    Jeff Schwab Guest

    Lasse Skyum wrote:
    > Hi All,
    >
    > Is it possible to detect (at compile-time) if an item is a basic type (int,
    > float, double,...) or an instance of a class/struct?


    There's a *great* treatment of this topic in the Josuttis templates book:

    http://www.josuttis.com/tmplbook/tmplbook.html

    Basically, you make a "traits" class to hold compile-time info about
    each type, and specialize as needed. Making complicated decisions based
    on the traits info is certainly possible; try googling for
    "metaprogramming."

    Good luck,
    Jeff
    Jeff Schwab, Dec 23, 2003
    #4
  5. Lasse Skyum

    Lasse Skyum Guest

    Thanks a lot guys, I've solved it now!

    By looking at some documents about "meta-programming" I worked something
    together.

    --
    Lasse


    > Hi All,
    >
    > Is it possible to detect (at compile-time) if an item is a basic type

    (int,
    > float, double,...) or an instance of a class/struct?
    >
    > I'm thinking something like: (obviosly this isn't working...)
    >
    > template<typename T>
    > CMyFileClass::Serialize(T &x)
    > {
    > #if IS_BASIC_TYPE(T)
    > // handle basic type
    > #else
    > // handle a class inherited from my CSerializable class
    > #endif
    > }
    >
    >
    > BTW, I'm writing serialization of data for a gameproject....
    >
    > Thanks for any help!
    > Lasse
    >
    >
    Lasse Skyum, Dec 23, 2003
    #5
  6. Lasse Skyum

    Jeff Schwab Guest

    Lasse Skyum wrote:
    > Thanks a lot guys, I've solved it now!
    >
    > By looking at some documents about "meta-programming" I worked something
    > together.
    >
    > --
    > Lasse


    Would you care to post it?
    Jeff Schwab, Dec 24, 2003
    #6
  7. Lasse Skyum

    Lasse Skyum Guest

    > Would you care to post it?

    Sure thing, please let me know if you have any additional ideas!


    // This is the base-class for my Input-streams
    class CZS_IStream
    {
    public:
    virtual int ReadBytes(void *pBytes,int iByteCount)=0;

    template<typename T>
    bool Read(T &v)
    {
    CZS_Serializer<T> s; // This is where the trick happens...
    return s.Read(this,v);
    }

    };

    // Every time data is read/written it goes through a version of
    CZS_Serializer.
    // This is the "default" one if none other is defined.
    template<typename T>
    class CZS_Serializer
    {
    public:
    bool Read(CZS_IStream *pS,T &v){return v.Serialize_Read(pS);}
    bool Write(CZS_OStream *pS,T &v){return v.Serialize_Write(pS);}
    };

    // All basic types are registered as "binary-types" by implementing a
    CZS_Serializer for them, that
    // uses ReadBytes and WriteBytes instead of the
    Serialize_Read/Serialize_Write functions.

    #define ZS_REGISTER_BINARYTYPE(CAClass) \
    template<>class CZS_Serializer<CAClass> \
    { \
    public: \
    bool Read(CZS_IStream *pS,T &v){return
    pS->ReadBytes(&v,sizeof(T))==sizeof(T);} \
    bool Write(CZS_OStream *pS,const T &v){return
    pS->WriteBytes(&v,sizeof(T));} \
    }; \

    ZS_REGISTER_BINARYTYPE(char)
    ZS_REGISTER_BINARYTYPE(unsigned char)
    ZS_REGISTER_BINARYTYPE(signed char)
    ZS_REGISTER_BINARYTYPE(int)
    ZS_REGISTER_BINARYTYPE(unsigned int)
    ZS_REGISTER_BINARYTYPE(long)
    ZS_REGISTER_BINARYTYPE(unsigned long)
    ZS_REGISTER_BINARYTYPE(__int8)
    ZS_REGISTER_BINARYTYPE(__int16)
    ZS_REGISTER_BINARYTYPE(__int32)
    ZS_REGISTER_BINARYTYPE(__int64)
    ZS_REGISTER_BINARYTYPE(float)
    ZS_REGISTER_BINARYTYPE(double)
    ZS_REGISTER_BINARYTYPE(long double)
    ZS_REGISTER_BINARYTYPE(bool)
    Lasse Skyum, Dec 24, 2003
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Chris

    Detecting document types

    Chris, Nov 24, 2003, in forum: Java
    Replies:
    0
    Views:
    333
    Chris
    Nov 24, 2003
  2. Jay

    detecting variable types

    Jay, Sep 22, 2004, in forum: Python
    Replies:
    15
    Views:
    578
    Alex Martelli
    Sep 25, 2004
  3. Replies:
    1
    Views:
    257
    Roedy Green
    May 7, 2007
  4. Replies:
    1
    Views:
    3,443
    Roedy Green
    Sep 23, 2007
  5. RobG

    Detecting support for event types

    RobG, Aug 15, 2008, in forum: Javascript
    Replies:
    15
    Views:
    190
    dhtml
    Aug 22, 2008
Loading...

Share This Page