array.hpp 3.85 KB
Newer Older
1
/*
2
    Copyright (c) 2007-2014 Contributors as noted in the AUTHORS file
3 4 5 6

    This file is part of 0MQ.

    0MQ is free software; you can redistribute it and/or modify it under
7
    the terms of the GNU Lesser General Public License as published by
8 9 10 11 12 13
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    0MQ is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
    GNU Lesser General Public License for more details.
15

16
    You should have received a copy of the GNU Lesser General Public License
17 18 19
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

20 21
#ifndef __ZMQ_ARRAY_INCLUDED__
#define __ZMQ_ARRAY_INCLUDED__
22 23 24 25 26 27 28

#include <vector>
#include <algorithm>

namespace zmq
{

29 30 31 32
    //  Base class for objects stored in the array. If you want to store
    //  same object in mutliple arrays, each of those arrays has to have
    //  different ID. The item itself has to be derived from instantiations of
    //  array_item_t template for all relevant IDs.
33

34
    template <int ID = 0> class array_item_t
35 36 37 38
    {
    public:

        inline array_item_t () :
39
            array_index (-1)
40 41 42 43 44 45 46 47 48
        {
        }

        //  The destructor doesn't have to be virtual. It is mad virtual
        //  just to keep ICC and code checking tools from complaining.
        inline virtual ~array_item_t ()
        {
        }

49
        inline void set_array_index (int index_)
50
        {
51
            array_index = index_;
52 53
        }

54
        inline int get_array_index ()
55
        {
56
            return array_index;
57 58
        }

59 60
    private:

61
        int array_index;
62 63

        array_item_t (const array_item_t&);
64
        const array_item_t &operator = (const array_item_t&);
65 66
    };

67
    //  Fast array implementation with O(1) access to item, insertion and
68
    //  removal. Array stores pointers rather than objects. The objects have
69
    //  to be derived from array_item_t<ID> class.
70

71
    template <typename T, int ID = 0> class array_t
72
    {
73 74 75 76
    private:

        typedef array_item_t <ID> item_t;

77 78 79 80
    public:

        typedef typename std::vector <T*>::size_type size_type;

81
        inline array_t ()
82 83 84
        {
        }

85
        inline ~array_t ()
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
        {
        }

        inline size_type size ()
        {
            return items.size ();
        }

        inline bool empty ()
        {
            return items.empty ();
        }

        inline T *&operator [] (size_type index_)
        {
            return items [index_];
        }

        inline void push_back (T *item_)
        {
106 107
            if (item_)
                ((item_t*) item_)->set_array_index ((int) items.size ());
108 109 110
            items.push_back (item_);
        }

111 112
        inline void erase (T *item_) {
            erase (((item_t*) item_)->get_array_index ());
113 114 115
        }

        inline void erase (size_type index_) {
116 117
            if (items.back ())
                ((item_t*) items.back ())->set_array_index ((int) index_);
118 119 120 121 122 123
            items [index_] = items.back ();
            items.pop_back ();
        }

        inline void swap (size_type index1_, size_type index2_)
        {
124 125 126 127
            if (items [index1_])
                ((item_t*) items [index1_])->set_array_index ((int) index2_);
            if (items [index2_])
                ((item_t*) items [index2_])->set_array_index ((int) index1_);
128 129 130 131 132 133 134 135 136 137
            std::swap (items [index1_], items [index2_]);
        }

        inline void clear ()
        {
            items.clear ();
        }

        inline size_type index (T *item_)
        {
138
            return (size_type) ((item_t*) item_)->get_array_index ();
139 140 141 142 143 144 145
        }

    private:

        typedef std::vector <T*> items_t;
        items_t items;

146
        array_t (const array_t&);
147
        const array_t &operator = (const array_t&);
148 149 150 151 152
    };

}

#endif
153