15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (C) 2009 Google Inc. All rights reserved.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * modification, are permitted provided that the following conditions are
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * met:
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *     * Redistributions of source code must retain the above copyright
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * notice, this list of conditions and the following disclaimer.
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *     * Redistributions in binary form must reproduce the above
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in the documentation and/or other materials provided with the
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * distribution.
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *     * Neither the name of Google Inc. nor the names of its
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * contributors may be used to endorse or promote products derived from
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * this software without specific prior written permission.
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef WebVector_h
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WebVector_h
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "WebCommon.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <limits>
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <stdlib.h>
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace blink {
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A simple vector class.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sample usage:
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   void Foo(WebVector<int>& result)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       WebVector<int> data(10);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       for (size_t i = 0; i < data.size(); ++i)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//           data[i] = ...
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//       result.swap(data);
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   }
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It is also possible to assign from other types of random access
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// containers:
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   void Foo(const std::vector<std::string>& input)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       WebVector<WebCString> cstrings = input;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       ...
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T>
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class WebVector {
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)public:
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    typedef T ValueType;
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~WebVector()
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        destroy();
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    explicit WebVector(size_t size = 0)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        initialize(size);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    template <typename U>
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebVector(const U* values, size_t size)
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        initializeFrom(values, size);
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebVector(const WebVector<T>& other)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        initializeFrom(other.m_ptr, other.m_size);
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    template <typename C>
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebVector(const C& other)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        initializeFrom(other.size() ? &other[0] : 0, other.size());
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebVector& operator=(const WebVector& other)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (this != &other)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            assign(other);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return *this;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    template <typename C>
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebVector<T>& operator=(const C& other)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (this != reinterpret_cast<const WebVector<T>*>(&other))
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            assign(other);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return *this;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    template <typename C>
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void assign(const C& other)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        assign(other.size() ? &other[0] : 0, other.size());
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    template <typename U>
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void assign(const U* values, size_t size)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        destroy();
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        initializeFrom(values, size);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t size() const { return m_size; }
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool isEmpty() const { return !m_size; }
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    T& operator[](size_t i)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        BLINK_ASSERT(i < m_size);
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return m_ptr[i];
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const T& operator[](size_t i) const
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        BLINK_ASSERT(i < m_size);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return m_ptr[i];
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool contains(const T& value) const
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (size_t i = 0; i < m_size; i++) {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (m_ptr[i] == value)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                return true;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    T* data() { return m_ptr; }
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const T* data() const { return m_ptr; }
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void swap(WebVector<T>& other)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        std::swap(m_ptr, other.m_ptr);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        std::swap(m_size, other.m_size);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)private:
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void initialize(size_t size)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        validateSize(size);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        m_size = size;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!m_size)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            m_ptr = 0;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            m_ptr = static_cast<T*>(::operator new(sizeof(T) * m_size));
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            for (size_t i = 0; i < m_size; ++i)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                new (&m_ptr[i]) T();
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    template <typename U>
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void initializeFrom(const U* values, size_t size)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        validateSize(size);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        m_size = size;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!m_size)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            m_ptr = 0;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else {
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            m_ptr = static_cast<T*>(::operator new(sizeof(T) * m_size));
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            for (size_t i = 0; i < m_size; ++i)
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                new (&m_ptr[i]) T(values[i]);
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void validateSize(size_t size)
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (std::numeric_limits<size_t>::max() / sizeof(T) < size)
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            abort();
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void destroy()
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        for (size_t i = 0; i < m_size; ++i)
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            m_ptr[i].~T();
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ::operator delete(m_ptr);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    T* m_ptr;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t m_size;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace blink
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)