Click here to Skip to main content
15,895,746 members
Articles / Desktop Programming / MFC

Introduction to ACF (Another C++ Framework)

Rate me:
Please Sign up or sign in to vote.
4.86/5 (36 votes)
27 May 200411 min read 136.4K   739   49  
This article introduces ACF, a C++ framework which brings the .NET framework to standard C++.
//---------------------------------------------------------------------
//
// Copyright (C) 2004 Yingle Jia
//
// Permission to copy, use, modify, sell and distribute this software is 
// granted provided this copyright notice appears in all copies. 
// This software is provided "as is" without express or implied warranty, 
// and with no claim as to its suitability for any purpose.
//
// AcfLanguage.h - utilities for C++ generic programming
//

#ifndef __Acf_Language__
#define __Acf_Language__

namespace Acf {
    namespace Language {

//---------------------------------------------------------------------
// IsVoid: true if the given type is "void"

template < typename T >
struct IsVoid
{
    enum { Value = false };
};

template <>
struct IsVoid<void>
{
    enum { Value = true };
};

//---------------------------------------------------------------------
// IsIntegral: true if the given type is a C++ integral type

template < typename T >
struct IsIntegral
{
    enum { Value = false };
};

template <>
struct IsIntegral<bool>
{
    enum { Value = true };
};

template <>
struct IsIntegral<sbyte>
{
    enum { Value = true };
};

template <>
struct IsIntegral<byte>
{
    enum { Value = true };
};

template <>
struct IsIntegral<wchar_t>
{
    enum { Value = true };
};

template <>
struct IsIntegral<short>
{
    enum { Value = true };
};

template <>
struct IsIntegral<ushort>
{
    enum { Value = true };
};

template <>
struct IsIntegral<int>
{
    enum { Value = true };
};

template <>
struct IsIntegral<uint>
{
    enum { Value = true };
};

template <>
struct IsIntegral<int64>
{
    enum { Value = true };
};

template <>
struct IsIntegral<uint64>
{
    enum { Value = true };
};

//---------------------------------------------------------------------
// IsFloat: true if the given type is a C++ floating point type

template < typename T >
struct IsFloat
{
    enum { Value = false };
};

template <>
struct IsFloat<float>
{
    enum { Value = true };
};

template <>
struct IsFloat<double>
{
    enum { Value = true };
};

//---------------------------------------------------------------------
// IsArithmatic: true if the given type is a integral type or floating 
// point type

template < typename T >
struct IsArithmatic
{
    enum { Value = IsIntegral<T>::Value || IsFloat<T>::Value };
};

//---------------------------------------------------------------------
// IsPointer: true if the given type is a pointer type

template < typename T >
struct IsPointer
{
    enum { Value = false };
};

template <typename T>
struct IsPointer<T*>
{
    enum { Value = true };
};

//---------------------------------------------------------------------
// IsMemberPointer: true if the given type is a member pointer type

namespace Internal {

template <class U>
struct IsMemberPointerTraits
{
    enum { Value = false };
};

template <class U, class V>
struct IsMemberPointerTraits<U V::*>
{
    enum { Value = true };
};

} // namespace Internal

template < typename T >
struct IsMemberPointer
{
    enum { Value = Internal::IsMemberPointerTraits<T>::Value };
};

//---------------------------------------------------------------------
// IsArray: true if the given type is an array type

namespace Internal {

template <class U>
struct IsArrayTraits
{
    enum { Value = false };
};

template <class U, int N>
struct IsArrayTraits<U (&)[N]>
{
    enum { Value = true };
};

} // namespace Internal

template < typename T >
struct IsArray
{
    enum { Value = Internal::IsArrayTraits<T>::Value };
};

//---------------------------------------------------------------------
// IsSame: true if the two given types are the same type

template < typename T, typename U >
struct IsSame
{
    enum { Value = false };
};

template < typename T >
struct IsSame< T, T >
{
    enum { Value = true };
};

//---------------------------------------------------------------------
// IsConvertible: true if type T is convertible to type U

template < typename T, typename U >
struct IsConvertible
{
    typedef char Small;
    class Big { char dummy[2]; };
    static Small Test(U);
    static Big Test(...);
    static T MakeT();

    enum { Value = (sizeof(Test(MakeT())) == sizeof(Small)) };
};

//---------------------------------------------------------------------
// IsSubclass: true if type T is a subclass of type U

template < class T, class U >
struct IsSubclass
{
    enum { Value = !IsSame<const U*, const void*>::Value && 
        IsConvertible<const T*, const U*>::Value && ! IsSame<const T*, const U*>::Value };
};

//---------------------------------------------------------------------
// IsSameOrSubclass: true if type T is same as or a subclass of type U

template < class T, class U >
struct IsSameOrSubclass
{
    enum { Value = !IsSame<const U*, const void*>::Value && 
        IsConvertible<const T*, const U*>::Value };
};

//---------------------------------------------------------------------
// NullType

struct NullType
{
};

//---------------------------------------------------------------------
// Int2Type

template <int V>
struct Int2Type
{
    enum { Value = V };
};

//---------------------------------------------------------------------
// SelectType: select type with a given condition

template<bool Condition, class A, class B> // true if A, false if B
struct SelectType
{
    typedef A Type;
};

template<class A, class B> // true if A, false if B
struct SelectType<false, A, B>
{
    typedef B Type;
};

//---------------------------------------------------------------------
// ParamType

template < typename T >
struct ParamType
{
    typedef typename SelectType<IsArithmatic<T>::Value || IsPointer<T>::Value, 
        T, const T&>::Type Type;
};

//---------------------------------------------------------------------
// Construct()
//     - constructs the elements with the default constructors.
//---------------------------------------------------------------------
template <typename T>
inline void Construct(T* p, int count)
{
    int i;
    try
    {
        for (i = 0; i < count; i++)
        {
            new(p + i) T;
        }
    }
    catch (...)
    {
        while (i > 0)
        {
            i--;
            p[i].~T();
        }
        throw;
    }
}

//---------------------------------------------------------------------
// Construct()
//     - constructs the elements with the copy constructors.
//---------------------------------------------------------------------
template <typename T>
inline void Construct(T* p, int count, const T* pSrc)
{
    int i;
    try
    {
        for (i = 0; i < count; i++)
        {
            new(p + i) T(pSrc[i]);
        }
    }
    catch (...)
    {
        while (i > 0)
        {
            i--;
            p[i].~T();
        }
        throw;
    }
}

//---------------------------------------------------------------------
// Destruct()
//     - destructs the elements
//---------------------------------------------------------------------
template <typename T>
inline void Destruct(T* p, int count)
{
    for (int i = 0; i < count; i++)
    {
        p[i].~T(); // destructors should never throw
    }
}

//---------------------------------------------------------------------
// Copy()
//     - copies n elements
//---------------------------------------------------------------------
template <typename T>
inline void Copy(const T* pSrc, T* pDst, int count)
{
    if (IsArithmatic<T>::Value || IsPointer<T>::Value)
    {
        memcpy(pDst, pSrc, count * sizeof(T));
    }
    else
    {
        for (int i = 0; i < count; i++)
            pDst[i] = pSrc[i];
    }
}

//---------------------------------------------------------------------
// New()
//---------------------------------------------------------------------
template <typename T>
inline T* New(int count)
{
    T* p = Acf::Alloc<T>(count);

    try
    {
        Construct(p, count);
    }
    catch (...)
    {
        Acf::Free(p);
        throw;
    }

    return p;
}

//---------------------------------------------------------------------
// Delete()
//---------------------------------------------------------------------
template <typename T>
inline void Delete(T* p, int count)
{
    Destruct(p, count);
    Acf::Free(p);
}

    } // namespace Language
} // namespace Acf

#endif // #ifndef __Acf_Language__

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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
China China
Yingle Jia is a software engineer located in Beijing, China. He currently works at IBM CSDL (China Software Development Lab). His interests include C++/COM/C#/.NET/XML, etc. He likes coding and writing.

He is the creator of ACF (Another C++ Framework) project. See http://acfproj.sourceforge.net/.

He also has a blog at http://blogs.wwwcoder.com/yljia/

Comments and Discussions