Click here to Skip to main content
15,885,757 members
Articles / Desktop Programming / MFC

What's New in ACF 0.3

Rate me:
Please Sign up or sign in to vote.
3.39/5 (7 votes)
23 Jun 20043 min read 40.4K   193   8  
This article introduces what's new in ACF (Another C++ Framework) version 0.3.
//---------------------------------------------------------------------
//
// 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.
//
// AcfCollectionBase.h
//
// Defines basic collecion traits and collection interfaces.
//

#ifndef __Acf_CollectionBase__
#define __Acf_CollectionBase__

namespace Acf {
    namespace Collections {

// Collection Traits

// NOTE: reference types shall be stored as RefPtr<X> in collections.

// Collection Traits Naming Convertion:
// - NullxxxTraits: means no-op (or throw)
// - SimplexxxTraits: for simple types like int
// - StructurexxxTraits: for C++ struct types

//---------------------------------------------------------------------
// ArgTypeTraits: controls how to pass arguments

// General types
template <typename T>
class ArgTypeTraits
{
public:
    typedef typename ParamType<T>::Type Type; // T or const T&
};

// Specialization for reference types, e.g. String
template <class T>
class ArgTypeTraits<RefPtr<T> >
{
public:
    typedef T* Type; // e.g. String*
};

//---------------------------------------------------------------------
// ClearTraits: controls how to clear elements, see Array<T>::Clear

template <typename T>
class NullClearTraits
{
public:
    static void Clear(T* p, int count)
    {
    }
};

template <typename T>
class SimpleClearTraits // works for simple value types
{
public:
    static void Clear(T* p, int count)
    {
        memset(p, 0, count * sizeof(T));
    }
};

template <typename T>
class ClearTraits : 
    public SelectType<IsArithmatic<T>::Value || IsPointer<T>::Value, 
        SimpleClearTraits<T>, NullClearTraits<T> >::Type
{
};

// Specialization for reference types, e.g. String
template <class T>
class ClearTraits<RefPtr<T> >
{
public:
    static void Clear(RefPtr<T>* p, int count)
    {
        for (int i = 0; i < count; i++)
            *(p++) = null; // release the reference
    }
};

//---------------------------------------------------------------------
// CompareTraits: controls how to compare elements and generate hash code
//                This is called by the default implementation of Comparer<T>.

template <typename T>
class NullCompareTraits
{
public:
    static bool Equals(typename ArgTypeTraits<T>::Type a, typename ArgTypeTraits<T>::Type b)
    {
        ACFASSERT(false); // don't know how to compare
        throw InvalidOperationException();
        return false;
    }

	static int Compare(typename ArgTypeTraits<T>::Type a, typename ArgTypeTraits<T>::Type b)
	{
        ACFASSERT(false); // don't know how to compare
        throw InvalidOperationException();
        return 0;
	}

	static int GetHashCode(typename ArgTypeTraits<T>::Type obj)
	{
        ACFASSERT(false); // do not know how to generate hash code
        throw InvalidOperationException();
		return 0;
	}
};

template <typename T>
class SimpleCompareTraits // for C++ fundamental types, enums and pointers
{
public:
    static bool Equals(T a, T b)
    {
		return (a == b);
    }

	static int Compare(T a, T b)
	{
		if (a < b)
			return -1;
		else if (a == b)
			return 0;
		else
			return 1;
	}

	static int GetHashCode(T obj)
	{
		return GetHashCodeImpl(obj);
	}

private:
    template <typename T>
    static int GetHashCodeImpl(T obj) // default for bool, wchar_t, int16, uint16, int32 and uint32
    {
		return static_cast<int>(obj);
    }
    template <typename T>
    static int GetHashCodeImpl(T* obj)
    {
        return PtrToLong(obj);
    }
    static int GetHashCodeImpl(int64 n)
    {
        return ((int)n) ^ ((int)(n >> 32));
    }
    static int GetHashCodeImpl(uint64 n)
    {
        return ((int)n) ^ ((int)(n >> 32));
    }
    static int GetHashCodeImpl(float f)
    {
        return *(int*)(&f);
    }
    static int GetHashCodeImpl(double d)
    {
        int64 n = *(int64*)(&d);
        return ((int)n) ^ ((int)(n >> 32));
    }
};

template <class T>
class StructureCompareTraits
{
public:
    static bool Equals(const T& a, const T& b)
    {
		return (a == b); // works for most types
    }

	static int Compare(const T& a, const T& b)
	{
        return T::Compare(a, b); // you should provide a static compare method
    }

	static int GetHashCode(const T& obj)
	{
		return obj.GetHashCode(); // you should provide an instance hash method
	}
};

template <typename T>
class CompareTraits : 
    public SelectType<IsArithmatic<T>::Value || IsPointer<T>::Value, 
        SimpleCompareTraits<T>, NullCompareTraits<T> >::Type
{
};

    } // namespace Collections
} // namespace Acf

namespace Acf {

template <typename T, int R = 1>
class Array;

} // namespace Acf

namespace Acf {
	namespace Collections {

//---------------------------------------------------------------------
// interface IEnumerator

template <typename T>
interface IEnumerator : public InterfaceBase
{
// Properties
	__declspec(property(get=get_Current)) T Current;
	virtual T get_Current() = 0;

// Methods
	virtual bool MoveNext() = 0;
};

//---------------------------------------------------------------------
// interface IEnumerable

template <typename T>
interface IEnumerable : public InterfaceBase
{
// Methods
	virtual RefPtr<IEnumerator<T> > GetEnumerator() = 0;
};

//---------------------------------------------------------------------
// interface ICollection

template <typename T>
interface ICollection : public IEnumerable<T>
{
// Declaractions
    typedef typename ArgTypeTraits<T>::Type    InArgType;

// Properties
	// Count
	__declspec(property(get=get_Count)) int Count;
	virtual int get_Count() = 0;
	// IsReadOnly
	__declspec(property(get=get_IsReadOnly)) bool IsReadOnly;
	virtual bool get_IsReadOnly() = 0;

// Methods
	virtual int Add(InArgType value) = 0;
	virtual bool Remove(InArgType value) = 0;
	virtual void Clear() = 0;
	virtual bool Contains(InArgType value) = 0;
    virtual void CopyTo(Array<T>* array, int index) = 0;
};

//---------------------------------------------------------------------
// interface IList

template <typename T>
interface IList : public ICollection<T>
{
// Properties
	// Item
    __declspec(property(get=get_Item, put=set_Item)) T Item[];
	virtual T get_Item(int index) = 0;
	virtual void set_Item(int index, InArgType value) = 0;

// Methods
    virtual int IndexOf(InArgType value) = 0;
	virtual void Insert(int index, InArgType value) = 0;
	virtual void RemoveAt(int index) = 0;
};

//---------------------------------------------------------------------
// struct KeyValuePair

template <typename K, typename V>
struct KeyValuePair
{
// Fields
public:
    K Key;
    V Value;

// Constructors
public:
    KeyValuePair() // for use in collections
    {
    }
    KeyValuePair(typename ArgTypeTraits<K>::Type key, typename ArgTypeTraits<V>::Type value) : 
        Key(key), Value(value)
    {
    }
};

template <typename K, typename V>
class ClearTraits<KeyValuePair<K, V> >
{
public:
    static void Clear(KeyValuePair<K, V>* p, int count)
    {
        for (int i = 0; i < count; i++, p++)
        {
            ClearTraits<K>::Clear(&p->Key, 1);
            ClearTraits<V>::Clear(&p->Value, 1);
        }
    }
};

//---------------------------------------------------------------------
// interface IDictionary

template <typename K, typename V>
interface IDictionary : public ICollection<KeyValuePair<K, V> >
{
// Declaractions
    typedef typename ArgTypeTraits<K>::Type    KeyInArgType;
    typedef typename ArgTypeTraits<V>::Type    ValueInArgType;

// Properties
	// Item
    __declspec(property(get=get_Item, put=set_Item)) V Item[];
    virtual V get_Item(KeyInArgType key) = 0;
	virtual void set_Item(KeyInArgType key, ValueInArgType value) = 0;
	// Keys
	__declspec(property(get=get_Keys)) RefPtr<ICollection<K> > Keys;
	virtual RefPtr<ICollection<K> > get_Keys() = 0;
	// Values
	__declspec(property(get=get_Values)) RefPtr<ICollection<V> > Values;
	virtual RefPtr<ICollection<V> > get_Values() = 0;

// Methods
	virtual bool ContainsKey(KeyInArgType key) = 0;
	virtual void Add(KeyInArgType key, ValueInArgType value) = 0;
	virtual bool Remove(KeyInArgType key) = 0;
};

//---------------------------------------------------------------------
// interface IComparable

template <typename T>
interface IComparable : public InterfaceBase
{
    typedef typename ArgTypeTraits<T>::Type    InArgType;

    virtual int CompareTo(InArgType obj) = 0;
    virtual bool Equals(InArgType obj) = 0;
};

//---------------------------------------------------------------------
// interface IComparer

template <typename T>
interface IComparer : public InterfaceBase
{
    typedef typename ArgTypeTraits<T>::Type    InArgType;

	virtual int Compare(InArgType a, InArgType b) = 0;
	virtual bool Equals(InArgType a, InArgType b) = 0;
  	virtual int GetHashCode(InArgType obj) = 0;
};

//---------------------------------------------------------------------
// CompareTraits

// Specialization for reference types, e.g. String
template <class T>
class CompareTraits<RefPtr<T> >
{
public:
	static bool Equals(T* a, T* b)
    {
        return Object::Equals(Acf::Internal::GetObject(a), 
            Acf::Internal::GetObject(b));
    }

	static int Compare(T* a, T* b)
    {
        // Check equal reference and null reference
        if (a == b)
            return 0;
        if (a == null)
            return -1;
        if (b == null)
            return 1;

        // This will be a compile-time error if T doesn't implement IComparable<RefPtr<T> >
        return CompareImpl(a, b);
    }

    static int GetHashCode(T* obj)
    {
        ACFASSERT(obj != null);
		return Acf::Internal::GetObject(obj)->GetHashCode();
    }

private:
    static int CompareImpl(IComparable<RefPtr<T> >* a, T* b)
    {
        return a->CompareTo(b);
    }
};

//---------------------------------------------------------------------
// FOREACH

#define __ACF_ENUM_T(c)    Enumerator<sizeof(SelectEnumType(c))>

// c: collection or array, cannot be null, cannot be "this"
#define ACF_FOREACH(Type, var, c) \
    if (__ACF_ENUM_T(c)::IteratorType __it = __ACF_ENUM_T(c)::BeginEnum(c)) \
        for (Type var; __ACF_ENUM_T(c)::MoveNext(c, __it, var); )

#ifndef FOREACH
#define FOREACH ACF_FOREACH
#endif

typedef char (&IEnumerableType)[1];
typedef char (&ArrayType      )[2];

template <int>
struct Enumerator; // no body

// Collection (default)

IEnumerableType SelectEnumType(...);

template <>
struct Enumerator<sizeof(IEnumerableType)>
{
public:
    typedef RefPtr<InterfaceBase>    IteratorType;

    template <typename T>
    static RefPtr<InterfaceBase> BeginEnum(IEnumerable<T>* c)
    {
        return c->GetEnumerator();
    }

    template <typename T>
    static RefPtr<InterfaceBase> BeginEnum(const RefPtr<T>& c)
    {
        return BeginEnum(c.Pointer);
    }

    template <typename T, typename U>
    static bool MoveNext(IEnumerable<T>* c, RefPtr<InterfaceBase>& it, U& var)
    {
        IEnumerator<T>* enumerator = static_cast<IEnumerator<T>*>(it.Pointer);

        if (!enumerator->MoveNext())
            return false;

        var = enumerator->Current;
        return true;
    }

    template <typename T, typename U>
    static bool MoveNext(const RefPtr<T>& c, RefPtr<InterfaceBase>& it, U& var)
    {
        return MoveNext(c.Pointer, it, var);
    }
};

// Array (single-dimensional)

template <typename T>
struct IteratorWrapper
{
    T it;

    IteratorWrapper(const T& it)
    {
        this->it = it;
    }

    operator bool() const
    {
        return true;
    }
};

template <typename T>
ArrayType SelectEnumType(Acf::Array<T>*);
template <typename T>
ArrayType SelectEnumType(const RefPtr<Acf::Array<T> >&);

template <>
struct Enumerator<sizeof(ArrayType)>
{
public:
    typedef IteratorWrapper<int>    IntIteratorWrapper;
    typedef IntIteratorWrapper    IteratorType;

    template <typename T>
    static IntIteratorWrapper BeginEnum(Acf::Array<T>* array)
    {
        return 0;
    }

    template <typename T>
    static IntIteratorWrapper BeginEnum(const RefPtr<Acf::Array<T> >& array)
    {
        return BeginEnum(array.Pointer);
    }

    template <typename T, typename U>
    static bool MoveNext(Acf::Array<T>* array, IntIteratorWrapper& itw, U& var)
    {
        if (itw.it >= array->Length)
            return false;

        var = array->GetValue(itw.it);
        ++itw.it;
        return true;
    }

    template <typename T, typename U>
    static bool MoveNext(const RefPtr<Acf::Array<T> >& array, IntIteratorWrapper& itw, U& var)
    {
        return MoveNext(array.Pointer, itw, var);
    }
};

	} // namespace Collections
} // namespace Acf

#endif // #ifndef __AcfCollectionBase__

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