/*
 * Copyright (C) 2009 Google Inc. 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.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * 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 SKY_ENGINE_PUBLIC_PLATFORM_WEBVECTOR_H_
#define SKY_ENGINE_PUBLIC_PLATFORM_WEBVECTOR_H_

#include <stdlib.h>
#include <algorithm>
#include <limits>
#include "sky/engine/public/platform/WebCommon.h"

namespace blink {

// A simple vector class.
//
// Sample usage:
//
//   void Foo(WebVector<int>& result)
//   {
//       WebVector<int> data(10);
//       for (size_t i = 0; i < data.size(); ++i)
//           data[i] = ...
//       result.swap(data);
//   }
//
// It is also possible to assign from other types of random access
// containers:
//
//   void Foo(const std::vector<std::string>& input)
//   {
//       WebVector<WebCString> cstrings = input;
//       ...
//   }
//
template <typename T>
class WebVector {
public:
    typedef T ValueType;

    ~WebVector()
    {
        destroy();
    }

    explicit WebVector(size_t size = 0)
    {
        initialize(size);
    }

    template <typename U>
    WebVector(const U* values, size_t size)
    {
        initializeFrom(values, size);
    }

    WebVector(const WebVector<T>& other)
    {
        initializeFrom(other.m_ptr, other.m_size);
    }

    template <typename C>
    WebVector(const C& other)
    {
        initializeFrom(other.size() ? &other[0] : 0, other.size());
    }

    WebVector& operator=(const WebVector& other)
    {
        if (this != &other)
            assign(other);
        return *this;
    }

    template <typename C>
    WebVector<T>& operator=(const C& other)
    {
        if (this != reinterpret_cast<const WebVector<T>*>(&other))
            assign(other);
        return *this;
    }

    template <typename C>
    void assign(const C& other)
    {
        assign(other.size() ? &other[0] : 0, other.size());
    }

    template <typename U>
    void assign(const U* values, size_t size)
    {
        destroy();
        initializeFrom(values, size);
    }

    size_t size() const { return m_size; }
    bool isEmpty() const { return !m_size; }

    T& operator[](size_t i)
    {
        BLINK_ASSERT(i < m_size);
        return m_ptr[i];
    }
    const T& operator[](size_t i) const
    {
        BLINK_ASSERT(i < m_size);
        return m_ptr[i];
    }

    bool contains(const T& value) const
    {
        for (size_t i = 0; i < m_size; i++) {
            if (m_ptr[i] == value)
                return true;
        }
        return false;
    }

    T* data() { return m_ptr; }
    const T* data() const { return m_ptr; }

    void swap(WebVector<T>& other)
    {
        std::swap(m_ptr, other.m_ptr);
        std::swap(m_size, other.m_size);
    }

private:
    void initialize(size_t size)
    {
        validateSize(size);
        m_size = size;
        if (!m_size)
            m_ptr = 0;
        else {
            m_ptr = static_cast<T*>(::operator new(sizeof(T) * m_size));
            for (size_t i = 0; i < m_size; ++i)
                new (&m_ptr[i]) T();
        }
    }

    template <typename U>
    void initializeFrom(const U* values, size_t size)
    {
        validateSize(size);
        m_size = size;
        if (!m_size)
            m_ptr = 0;
        else {
            m_ptr = static_cast<T*>(::operator new(sizeof(T) * m_size));
            for (size_t i = 0; i < m_size; ++i)
                new (&m_ptr[i]) T(values[i]);
        }
    }

    void validateSize(size_t size)
    {
        if (std::numeric_limits<size_t>::max() / sizeof(T) < size)
            abort();
    }

    void destroy()
    {
        for (size_t i = 0; i < m_size; ++i)
            m_ptr[i].~T();
        ::operator delete(m_ptr);
    }

    T* m_ptr;
    size_t m_size;
};

} // namespace blink

#endif  // SKY_ENGINE_PUBLIC_PLATFORM_WEBVECTOR_H_
