/*
 *  TypeHelpers.h
 *  
 *  Copyright 2005 The Android Open Source Project
 *
 */

#ifndef ANDROID_TYPE_HELPERS_H
#define ANDROID_TYPE_HELPERS_H

#include <new>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>

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

namespace android {

/*
 * Types traits
 */
    
template <typename T> struct trait_trivial_ctor  { enum { value = false }; };
template <typename T> struct trait_trivial_dtor  { enum { value = false }; };
template <typename T> struct trait_trivial_copy  { enum { value = false }; };
template <typename T> struct trait_trivial_assign{ enum { value = false }; };

template <typename T> struct trait_pointer     { enum { value = false }; };    
template <typename T> struct trait_pointer<T*> { enum { value = true }; };

#define ANDROID_BASIC_TYPES_TRAITS( T )                                       \
    template<> struct trait_trivial_ctor< T >  { enum { value = true }; };    \
    template<> struct trait_trivial_dtor< T >  { enum { value = true }; };    \
    template<> struct trait_trivial_copy< T >  { enum { value = true }; };    \
    template<> struct trait_trivial_assign< T >{ enum { value = true }; }; 

#define ANDROID_TYPE_TRAITS( T, ctor, dtor, copy, assign )                    \
    template<> struct trait_trivial_ctor< T >  { enum { value = ctor }; };    \
    template<> struct trait_trivial_dtor< T >  { enum { value = dtor }; };    \
    template<> struct trait_trivial_copy< T >  { enum { value = copy }; };    \
    template<> struct trait_trivial_assign< T >{ enum { value = assign }; }; 

template <typename TYPE>
struct traits {
    enum {
        is_pointer          = trait_pointer<TYPE>::value,
        has_trivial_ctor    = is_pointer || trait_trivial_ctor<TYPE>::value,
        has_trivial_dtor    = is_pointer || trait_trivial_dtor<TYPE>::value,
        has_trivial_copy    = is_pointer || trait_trivial_copy<TYPE>::value,
        has_trivial_assign  = is_pointer || trait_trivial_assign<TYPE>::value   
    };
};

template <typename T, typename U>
struct aggregate_traits {
    enum {
        is_pointer          = false,
        has_trivial_ctor    = traits<T>::has_trivial_ctor && traits<U>::has_trivial_ctor,
        has_trivial_dtor    = traits<T>::has_trivial_dtor && traits<U>::has_trivial_dtor,
        has_trivial_copy    = traits<T>::has_trivial_copy && traits<U>::has_trivial_copy,
        has_trivial_assign  = traits<T>::has_trivial_assign && traits<U>::has_trivial_assign
    };
};

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

/*
 * basic types traits
 */
 
ANDROID_BASIC_TYPES_TRAITS( void );
ANDROID_BASIC_TYPES_TRAITS( bool );
ANDROID_BASIC_TYPES_TRAITS( char );
ANDROID_BASIC_TYPES_TRAITS( unsigned char );
ANDROID_BASIC_TYPES_TRAITS( short );
ANDROID_BASIC_TYPES_TRAITS( unsigned short );
ANDROID_BASIC_TYPES_TRAITS( int );
ANDROID_BASIC_TYPES_TRAITS( unsigned int );
ANDROID_BASIC_TYPES_TRAITS( long );
ANDROID_BASIC_TYPES_TRAITS( unsigned long );
ANDROID_BASIC_TYPES_TRAITS( long long );
ANDROID_BASIC_TYPES_TRAITS( unsigned long long );
ANDROID_BASIC_TYPES_TRAITS( float );
ANDROID_BASIC_TYPES_TRAITS( double );

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

    
/*
 * compare and order types
 */

template<typename TYPE> inline
int strictly_order_type(const TYPE& lhs, const TYPE& rhs) {
    return (lhs < rhs) ? 1 : 0;
}

template<typename TYPE> inline
int compare_type(const TYPE& lhs, const TYPE& rhs) {
    return strictly_order_type(rhs, lhs) - strictly_order_type(lhs, rhs);
}

/*
 * create, destroy, copy and assign types...
 */
 
template<typename TYPE> inline
void construct_type(TYPE* p, size_t n) {
    if (!traits<TYPE>::has_trivial_ctor) {
        while (n--) {
            new(p++) TYPE;
        }
    }
}

template<typename TYPE> inline
void destroy_type(TYPE* p, size_t n) {
    if (!traits<TYPE>::has_trivial_dtor) {
        while (n--) {
            p->~TYPE();
            p++;
        }
    }
}

template<typename TYPE> inline
void copy_type(TYPE* d, const TYPE* s, size_t n) {
    if (!traits<TYPE>::has_trivial_copy) {
        while (n--) {
            new(d) TYPE(*s);
            d++, s++;
        }
    } else {
        memcpy(d,s,n*sizeof(TYPE));
    }
}

template<typename TYPE> inline
void assign_type(TYPE* d, const TYPE* s, size_t n) {
    if (!traits<TYPE>::has_trivial_assign) {
        while (n--) {
            *d++ = *s++;
        }
    } else {
        memcpy(d,s,n*sizeof(TYPE));
    }
}

template<typename TYPE> inline
void splat_type(TYPE* where, const TYPE* what, size_t n) {
    if (!traits<TYPE>::has_trivial_copy) {
        while (n--) {
            new(where) TYPE(*what);
            where++;
        }
    } else {
         while (n--) {
             *where++ = *what;
        }
    }
}

template<typename TYPE> inline
void move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) {
    if (!traits<TYPE>::has_trivial_copy || !traits<TYPE>::has_trivial_dtor) {
        d += n;
        s += n;
        while (n--) {
            --d, --s;
            if (!traits<TYPE>::has_trivial_copy) {
                new(d) TYPE(*s);
            } else {
                *d = *s;
            }
            if (!traits<TYPE>::has_trivial_dtor) {
                s->~TYPE();
            }
        }
    } else {
        memmove(d,s,n*sizeof(TYPE));
    }
}

template<typename TYPE> inline
void move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) {
    if (!traits<TYPE>::has_trivial_copy || !traits<TYPE>::has_trivial_dtor) {
        while (n--) {
            if (!traits<TYPE>::has_trivial_copy) {
                new(d) TYPE(*s);
            } else {
                *d = *s;
            }
            if (!traits<TYPE>::has_trivial_dtor) {
                s->~TYPE();
            }
            d++, s++;
        }
    } else {
        memmove(d,s,n*sizeof(TYPE));
    }
}
// ---------------------------------------------------------------------------

/*
 * a key/value pair
 */

template <typename KEY, typename VALUE>
struct key_value_pair_t {
    KEY     key;
    VALUE   value;
    key_value_pair_t() { }
    key_value_pair_t(const key_value_pair_t& o) : key(o.key), value(o.value) { }
    key_value_pair_t(const KEY& k, const VALUE& v) : key(k), value(v)  { }
    key_value_pair_t(const KEY& k) : key(k) { }
    inline bool operator < (const key_value_pair_t& o) const {
        return strictly_order_type(key, o.key);
    }
};

template<>
template <typename K, typename V>
struct trait_trivial_ctor< key_value_pair_t<K, V> >
{ enum { value = aggregate_traits<K,V>::has_trivial_ctor }; };
template<> 
template <typename K, typename V>
struct trait_trivial_dtor< key_value_pair_t<K, V> >
{ enum { value = aggregate_traits<K,V>::has_trivial_dtor }; };
template<> 
template <typename K, typename V>
struct trait_trivial_copy< key_value_pair_t<K, V> >
{ enum { value = aggregate_traits<K,V>::has_trivial_copy }; };
template<> 
template <typename K, typename V>
struct trait_trivial_assign< key_value_pair_t<K, V> >
{ enum { value = aggregate_traits<K,V>::has_trivial_assign};};

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

}; // namespace android

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

#endif // ANDROID_TYPE_HELPERS_H
