src/containers.h

changeset 72
03e4d9db3fd9
child 73
1ee9b312dc18
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/containers.h	Fri Jan 10 21:58:42 2014 +0200
@@ -0,0 +1,227 @@
+#ifndef LIBCOBALT_CONTAINERS_H
+#define LIBCOBALT_CONTAINERS_H
+
+#include <cassert>
+#include <algorithm>
+#include <deque>
+#include <initializer_list>
+
+template<class T> class list
+{
+    public:
+        typedef typename ::std::deque<T> list_type;
+        typedef typename list_type::iterator it;
+        typedef typename list_type::const_iterator c_it;
+        typedef typename list_type::reverse_iterator r_it;
+        typedef typename list_type::const_reverse_iterator cr_it;
+        typedef T element_type;
+        typedef list<T> self_type;
+
+        list() {}
+        list (std::initializer_list<element_type> vals)
+        {
+            m_data = vals;
+        }
+
+        list (const list_type& a) : m_data (a) {}
+
+        it begin()
+        {
+            return m_data.begin();
+        }
+
+        c_it begin() const
+        {
+            return m_data.cbegin();
+        }
+
+        it end()
+        {
+            return m_data.end();
+        }
+
+        c_it end() const
+        {
+            return m_data.cend();
+        }
+
+        r_it rbegin()
+        {
+            return m_data.rbegin();
+        }
+
+        cr_it crbegin() const
+        {
+            return m_data.crbegin();
+        }
+
+        r_it rend()
+        {
+            return m_data.rend();
+        }
+
+        cr_it crend() const
+        {
+            return m_data.crend();
+        }
+
+        void erase (int pos)
+        {
+            assert (pos < size());
+            m_data.erase (m_data.begin() + pos);
+        }
+
+        element_type& push_front (const element_type& value)
+        {
+            m_data.push_front (value);
+            return m_data[0];
+        }
+
+        element_type& push_back (const element_type& value)
+        {
+            m_data.push_back (value);
+            return m_data[m_data.size() - 1];
+        }
+
+        void push_back (const self_type& vals)
+        {
+            for (const T & val : vals)
+                push_back (val);
+        }
+
+        bool pop (T& val)
+        {
+            if (size() == 0)
+                return false;
+
+            val = m_data[size() - 1];
+            erase (size() - 1);
+            return true;
+        }
+
+        T& operator<< (const T& value)
+        {
+            return push_back (value);
+        }
+
+        void operator<< (const self_type& vals)
+        {
+            push_back (vals);
+        }
+
+        bool operator>> (T& value)
+        {
+            return pop (value);
+        }
+
+        self_type reverse() const
+        {
+            self_type rev;
+
+            for (const T & val : *this)
+                val >> rev;
+
+            return rev;
+        }
+
+        void clear()
+        {
+            m_data.clear();
+        }
+
+        void insert (int pos, const element_type& value)
+        {
+            m_data.insert (m_data.begin() + pos, value);
+        }
+
+        void makeUnique()
+        {
+            // Remove duplicate entries. For this to be effective, the vector must be
+            // sorted first.
+            sort();
+            it pos = std::unique (begin(), end());
+            resize (std::distance (begin(), pos));
+        }
+
+        int size() const
+        {
+            return m_data.size();
+        }
+
+        element_type& operator[] (int n)
+        {
+            assert (n < size());
+            return m_data[n];
+        }
+
+        const element_type& operator[] (int n) const
+        {
+            assert (n < size());
+            return m_data[n];
+        }
+
+        void resize (std::ptrdiff_t size)
+        {
+            m_data.resize (size);
+        }
+
+        void sort()
+        {
+            std::sort (begin(), end());
+        }
+
+        int find (const element_type& needle)
+        {
+            int i = 0;
+
+            for (const element_type & hay : *this)
+            {
+                if (hay == needle)
+                    return i;
+
+                i++;
+            }
+
+            return -1;
+        }
+
+        void remove (const element_type& it)
+        {
+            int idx;
+
+            if ( (idx = find (it)) != -1)
+                erase (idx);
+        }
+
+        inline bool is_empty() const
+        {
+            return size() == 0;
+        }
+
+        self_type mid (int a, int b) const
+        {
+            assert (a >= 0 && b >= 0 && a < size() && b < size() && a <= b);
+            self_type result;
+
+            for (int i = a; i <= b; ++i)
+                result << operator[] (i);
+
+            return result;
+        }
+
+        inline const list_type& std_deque() const
+        {
+            return m_data;
+        }
+
+    private:
+        list_type m_data;
+};
+
+template<class T> list<T>& operator>> (const T& value, list<T>& haystack)
+{
+    haystack.push_front (value);
+    return haystack;
+}
+
+#endif // LIBCOBALT_CONTAINERS_H

mercurial