/* -*- c++ -*- */
/*
 * Copyright (C) 2009 The Android Open Source Project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef ANDROID_ASTL_MEMORY__
#define ANDROID_ASTL_MEMORY__

#include "type_traits.h"
#include <new>  // for placement new
#include <cstring>
#include <algorithm>
#include <iterator>
#include <limits>

#if defined(_InputIterator) || defined(_ForwardIterator)
#error "_InputIterator or _ForwardIterator are already defined."
#endif

namespace std {

// uninitialized_copy is used when memory allocation and object
// construction need to happen in separate steps. For each instance in
// the input range a copy is created and placed in the corresponding
// memory pointed by dest.
// If the input range is made of pod instances AND both input and
// destination iterators are random access ones, uninitialized_copy
// degrades to a memmove call.
// Returns an iterator pass the end of the destination range.

// Default implementation used when iterators are not random access
// and the value type are not both POD.
template<bool, typename _InputIteratorTag, typename _ForwardIteratorTag>
struct __uninitialized_copy
{
    template<typename _InputIterator, typename _ForwardIterator>
    static _ForwardIterator uninitialized_copy(_InputIterator begin,
                                               _InputIterator end,
                                               _ForwardIterator dest) {
        typedef typename iterator_traits<_ForwardIterator>::
                value_type value_type;
        for (; begin != end; ++begin, ++dest) {
            new (static_cast<void*>(&*dest)) value_type(*begin);
        }
        return dest;
    }
};

// Full specialization when the src and dest types are pod && both
// iterators are random access.
template<>
struct __uninitialized_copy<true,
                            random_access_iterator_tag,
                            random_access_iterator_tag>
{
    template<typename _InputIterator, typename _ForwardIterator>
    static _ForwardIterator uninitialized_copy(_InputIterator begin,
                                               _InputIterator end,
                                               _ForwardIterator dest)
    {
        typedef typename iterator_traits<_InputIterator>::
                difference_type difference_type;
        const difference_type len = std::distance(begin, end);
        const difference_type kMaxSize =
                std::numeric_limits<difference_type>::max();

        typedef typename iterator_traits<_ForwardIterator>::
                value_type value_type;
        const size_t kSize = sizeof(value_type);

        if (len > 0 &&
            static_cast<size_t>(kMaxSize) / kSize > static_cast<size_t>(len)) {
            std::memmove(static_cast<void*>(&*dest),
                         static_cast<const void*>(&*begin), kSize * len);
            return dest + len;
        } else {
            return dest;
        }
    }
};

// TODO: If placement new degrades to assignement for POD, we can get
// rid of this one.
// Bothe pod but not both random access
template<> struct __uninitialized_copy<true,
                                       input_iterator_tag,
                                       forward_iterator_tag>
{
    template<typename _InputIterator, typename _ForwardIterator>
    static _ForwardIterator uninitialized_copy(_InputIterator begin,
                                               _InputIterator end,
                                               _ForwardIterator dest) {
        for (; begin != end; ++begin, ++dest) {
            *dest = *begin;
        }
        return dest;
    }
};


template<typename _InputIterator, typename _ForwardIterator>
inline _ForwardIterator uninitialized_copy(_InputIterator begin,
                                           _InputIterator end,
                                           _ForwardIterator dest)
{
    typedef typename iterator_traits<_InputIterator>::value_type _ValueType1;
    typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2;

    const bool both_pod =
            is_pod<_ValueType1>::value && is_pod<_ValueType2>::value;

    return __uninitialized_copy<both_pod,
            typename iterator_traits<_InputIterator>::iterator_category,
            typename iterator_traits<_ForwardIterator>::iterator_category>::
            uninitialized_copy(begin, end, dest);
}

// TODO: replace pointers with iterator below.

// uninitialized_fill is used when memory allocation and object
// construction need to happen in separate steps. uninitialized_fill
// creates a copy of 'obj' in the location pointed by the interator,
// using the object's class copy constructor.

template<bool> struct __uninitialized_fill
{
    template<typename _ForwardIterator, typename _T>
    static void uninitialized_fill(_ForwardIterator *begin,
                                   _ForwardIterator *end,
                                   const _T& val)
    {
        for (; begin < end; ++begin)
            new (static_cast<void*>(&*begin)) _ForwardIterator(val);
    }
};

template<> struct __uninitialized_fill<true>
{
    template<typename _ForwardIterator, typename _T>
    static void uninitialized_fill(_ForwardIterator *begin,
                                   _ForwardIterator *end,
                                   const _T& val)
    {
        std::fill(begin, end, val);
    }
};

// The real STL takes iterators, we take pointers for now.
template<typename _ForwardIterator, typename _T>
inline void uninitialized_fill(_ForwardIterator *begin,
                               _ForwardIterator *end,
                               const _T& val)
{
    const bool pod = is_pod<_ForwardIterator>::value;
    return __uninitialized_fill<pod>::uninitialized_fill(begin, end, val);
}

}  // namespace std

#endif  // ANDROID_ASTL_MEMORY__
