/*
 * Copyright (C) 2005 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_TYPE_HELPERS_H
#define ANDROID_TYPE_HELPERS_H

#include <new>
#include <type_traits>

#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_move { enum { value = false }; };
template <typename T> struct trait_pointer      { enum { value = false }; };    
template <typename T> struct trait_pointer<T*>  { enum { value = true }; };

template <typename TYPE>
struct traits {
    enum {
        // whether this type is a pointer
        is_pointer          = trait_pointer<TYPE>::value,
        // whether this type's constructor is a no-op
        has_trivial_ctor    = is_pointer || trait_trivial_ctor<TYPE>::value,
        // whether this type's destructor is a no-op
        has_trivial_dtor    = is_pointer || trait_trivial_dtor<TYPE>::value,
        // whether this type type can be copy-constructed with memcpy
        has_trivial_copy    = is_pointer || trait_trivial_copy<TYPE>::value,
        // whether this type can be moved with memmove
        has_trivial_move    = is_pointer || trait_trivial_move<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_move    = 
            traits<T>::has_trivial_move && traits<U>::has_trivial_move
    };
};

#define ANDROID_TRIVIAL_CTOR_TRAIT( T ) \
    template<> struct trait_trivial_ctor< T >   { enum { value = true }; };

#define ANDROID_TRIVIAL_DTOR_TRAIT( T ) \
    template<> struct trait_trivial_dtor< T >   { enum { value = true }; };

#define ANDROID_TRIVIAL_COPY_TRAIT( T ) \
    template<> struct trait_trivial_copy< T >   { enum { value = true }; };

#define ANDROID_TRIVIAL_MOVE_TRAIT( T ) \
    template<> struct trait_trivial_move< T >   { enum { value = true }; };

#define ANDROID_BASIC_TYPES_TRAITS( T ) \
    ANDROID_TRIVIAL_CTOR_TRAIT( T ) \
    ANDROID_TRIVIAL_DTOR_TRAIT( T ) \
    ANDROID_TRIVIAL_COPY_TRAIT( T ) \
    ANDROID_TRIVIAL_MOVE_TRAIT( T )

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

/*
 * 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 move types...
 */

template<typename TYPE> inline
void construct_type(TYPE* p, size_t n) {
    if (!traits<TYPE>::has_trivial_ctor) {
        while (n > 0) {
            n--;
            new(p++) TYPE;
        }
    }
}

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

template<typename TYPE>
typename std::enable_if<traits<TYPE>::has_trivial_copy>::type
inline
copy_type(TYPE* d, const TYPE* s, size_t n) {
    memcpy(d,s,n*sizeof(TYPE));
}

template<typename TYPE>
typename std::enable_if<!traits<TYPE>::has_trivial_copy>::type
inline
copy_type(TYPE* d, const TYPE* s, size_t n) {
    while (n > 0) {
        n--;
        new(d) TYPE(*s);
        d++, s++;
    }
}

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

template<typename TYPE>
struct use_trivial_move : public std::integral_constant<bool,
    (traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy)
    || traits<TYPE>::has_trivial_move
> {};

template<typename TYPE>
typename std::enable_if<use_trivial_move<TYPE>::value>::type
inline
move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) {
    memmove(d, s, n*sizeof(TYPE));
}

template<typename TYPE>
typename std::enable_if<!use_trivial_move<TYPE>::value>::type
inline
move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) {
    d += n;
    s += n;
    while (n > 0) {
        n--;
        --d, --s;
        if (!traits<TYPE>::has_trivial_copy) {
            new(d) TYPE(*s);
        } else {
            *d = *s;
        }
        if (!traits<TYPE>::has_trivial_dtor) {
            s->~TYPE();
        }
    }
}

template<typename TYPE>
typename std::enable_if<use_trivial_move<TYPE>::value>::type
inline
move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) {
    memmove(d, s, n*sizeof(TYPE));
}

template<typename TYPE>
typename std::enable_if<!use_trivial_move<TYPE>::value>::type
inline
move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) {
    while (n > 0) {
        n--;
        if (!traits<TYPE>::has_trivial_copy) {
            new(d) TYPE(*s);
        } else {
            *d = *s;
        }
        if (!traits<TYPE>::has_trivial_dtor) {
            s->~TYPE();
        }
        d++, s++;
    }
}

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

/*
 * a key/value pair
 */

template <typename KEY, typename VALUE>
struct key_value_pair_t {
    typedef KEY key_t;
    typedef VALUE value_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& operator=(const key_value_pair_t& o) {
        key = o.key;
        value = o.value;
        return *this;
    }
    key_value_pair_t(const KEY& k, const VALUE& v) : key(k), value(v)  { }
    explicit 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);
    }
    inline const KEY& getKey() const {
        return key;
    }
    inline const VALUE& getValue() const {
        return value;
    }
};

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 <typename K, typename V>
struct trait_trivial_dtor< key_value_pair_t<K, V> >
{ enum { value = aggregate_traits<K,V>::has_trivial_dtor }; };
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 <typename K, typename V>
struct trait_trivial_move< key_value_pair_t<K, V> >
{ enum { value = aggregate_traits<K,V>::has_trivial_move }; };

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

/*
 * Hash codes.
 */
typedef uint32_t hash_t;

template <typename TKey>
hash_t hash_type(const TKey& key);

/* Built-in hash code specializations */
#define ANDROID_INT32_HASH(T) \
        template <> inline hash_t hash_type(const T& value) { return hash_t(value); }
#define ANDROID_INT64_HASH(T) \
        template <> inline hash_t hash_type(const T& value) { \
                return hash_t((value >> 32) ^ value); }
#define ANDROID_REINTERPRET_HASH(T, R) \
        template <> inline hash_t hash_type(const T& value) { \
            R newValue; \
            static_assert(sizeof(newValue) == sizeof(value), "size mismatch"); \
            memcpy(&newValue, &value, sizeof(newValue)); \
            return hash_type(newValue); \
        }

ANDROID_INT32_HASH(bool)
ANDROID_INT32_HASH(int8_t)
ANDROID_INT32_HASH(uint8_t)
ANDROID_INT32_HASH(int16_t)
ANDROID_INT32_HASH(uint16_t)
ANDROID_INT32_HASH(int32_t)
ANDROID_INT32_HASH(uint32_t)
ANDROID_INT64_HASH(int64_t)
ANDROID_INT64_HASH(uint64_t)
ANDROID_REINTERPRET_HASH(float, uint32_t)
ANDROID_REINTERPRET_HASH(double, uint64_t)

template <typename T> inline hash_t hash_type(T* const & value) {
    return hash_type(uintptr_t(value));
}

}; // namespace android

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

#endif // ANDROID_TYPE_HELPERS_H
