array.hpp 3.22 KB
Newer Older
Gauthier Quesnel's avatar
Gauthier Quesnel committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
 * This file is part of VLE, a framework for multi-modeling, simulation
 * and analysis of complex dynamical systems.
 * https://www.vle-project.org
 *
 * Copyright (c) 2003-2018 Gauthier Quesnel <gauthier.quesnel@inra.fr>
 * Copyright (c) 2003-2018 ULCO http://www.univ-littoral.fr
 * Copyright (c) 2007-2018 INRA http://www.inra.fr
 *
 * See the AUTHORS or Authors.txt file for copyright owners and
 * contributors
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or (at
 * your option) any later version.
 *
 * This program 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 GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <type_traits>

namespace vle {
namespace glvle {

template<typename T>
struct DataArray<T>
{
    struct item
    {
        T item;
        int id; // (key << 16 | index) for alloced entries, (0 | nextFreeIndex)
                // for free list entries
    };

    // allocs items (max 64k), then Clear()
    void init(int count);

    // frees items
    void dispose();

    // resets data members, (runs destructors* on outstanding items,
    // *optional)
    void clear();

    T& Alloc(); // alloc (memclear* and/or construct*, *optional) an item from
                // freeList or items[maxUsed++], sets id to (nextKey++ << 16) |
                // index
    void Free(T&); // puts entry on free list (uses id to store next)

    int GetID(T&); // accessor to the id part if Item

    T& Get(id) // return item[id & 0xFFFF];
      T* TryToGet(
        id); // validates id, then returns item, returns null if invalid.  for
             // cases like AI references and others where 'the thing might have
             // been deleted out from under me'

    bool Next(T*&); // return next item where id & 0xFFFF0000 != 0 (ie items
                    // not on free list)

    std::vector<item> items;
    Item* items;
    int maxSize;  // total size
    int maxUsed;  // highest index ever alloced
    int count;    // num alloced items
    int nextKey;  // [1..2^16] (don't let == 0)
    int freeHead; // index of first free entry
};

template<typename T>
void
DataArray<T>::init(int count)
{
    items.resize(static_cast<size_t>(count));
}

template<typename T>
void
DataArray<T>::dispose()
{
    items.resize(static_cast<size_t>(0));
    items.shrink_to_fit();
}

template<typename T, true>
void
Do_clear(std::vector<T>& items)
{}

template<typename T, false>
void
Do_clear(std::vector<T>& items)
{
    std::for_each(
      std::begin(items), std::end(items), [](auto& elem) { elem.~T(); });
}

template<typename T>
void
DataArray<T>::clear()
{
    Do_clear<T, std::is_trivial<T>::value>(items);
}

template<typename T>
T&
DataArray<T>::alloc();
{}

// alloc (memclear* and/or construct*, *optional) an item from
// freeList or items[maxUsed++], sets id to (nextKey++ << 16) |
// index

} // glvle
} // vle