array.hpp 3.9 KB
Newer Older
1
/*
2 3
    Copyright (c) 2007-2011 iMatix Corporation
    Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file
4 5 6 7

    This file is part of 0MQ.

    0MQ is free software; you can redistribute it and/or modify it under
8
    the terms of the GNU Lesser General Public License as published by
9 10 11 12 13 14
    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
15
    GNU Lesser General Public License for more details.
16

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

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

#include <vector>
#include <algorithm>

namespace zmq
{

30 31 32 33
    //  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.
34

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

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

        //  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 ()
        {
        }

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

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

60 61
    private:

62
        int array_index;
63 64

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

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

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

        typedef array_item_t <ID> item_t;

78 79 80 81
    public:

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

82
        inline array_t ()
83 84 85
        {
        }

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

        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_)
        {
107 108
            if (item_)
                ((item_t*) item_)->set_array_index ((int) items.size ());
109 110 111
            items.push_back (item_);
        }

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

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

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

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

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

    private:

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

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

}

#endif
154