File: tjindex.cpp

package info (click to toggle)
odin 2.0.5-8
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 9,196 kB
  • sloc: cpp: 62,638; sh: 4,541; makefile: 779
file content (170 lines) | stat: -rw-r--r-- 5,303 bytes parent folder | download | duplicates (8)
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#include "tjindex.h"
#include "tjtest.h"
#include "tjlog_code.h"
#include "tjhandler_code.h"

const char* Index::get_compName() {return "Index";}
LOGGROUNDWORK(Index)


///////////////////////////////////////////////////////////////////////////////////////////


unsigned int UniqueIndexMap::get_index(STD_list<unsigned int>::iterator& index, const STD_string& type, unsigned int max_instances) {
  Log<Index> odinlog(type.c_str(),"get_index");
  STD_list<unsigned int>& indices=(*this)[type];
  if(index==indices.end()) assign_index(index,type);
  if(max_instances && ((*index)>=max_instances)) {
    ODINLOG(odinlog,errorLog) << "maximum number of indices exceeded for type " << type << STD_endl;
    return 0;
  }
  ODINLOG(odinlog,normalDebug) <<  "returning index=" << *index << STD_endl;
  return (*index);
}


void UniqueIndexMap::remove_index(const STD_list<unsigned int>::iterator& index, const STD_string& type) {
  Log<Index> odinlog(type.c_str(),"remove_index");
  STD_list<unsigned int>& indices=(*this)[type];
  if(index!=indices.end()) {
    ODINLOG(odinlog,normalDebug) << "Trying to remove index=" << *index << STD_endl;
    indices.erase(index);
    contiguous=false;
  }
}


unsigned int UniqueIndexMap::assign_index(STD_list<unsigned int>::iterator& index, const STD_string& type) {
  Log<Index> odinlog(type.c_str(),"assign_index");
  STD_list<unsigned int>& indices=(*this)[type];
  index=indices.end();
  unsigned int i=0;
  STD_list<unsigned int>::iterator iter;
  if(contiguous){ //if the list is contiguous
    iter=indices.end();
    if(indices.begin()!=indices.end())//use the last member +1 or leave 0
      i= *(--indices.end())+1;
  } else {//if list is not complete find the first "gap"
    for(iter=indices.begin();iter!=indices.end() && *iter==i;++iter)
      i++;
  }
  index=indices.insert(iter,i);//insert i into the gap (or the end)
  ODINLOG(odinlog,normalDebug) << "adding index=" << i << STD_endl;

  for(;iter!=indices.end() && *iter==(i+1);++iter); //check for a gap behind
  contiguous = (iter==indices.end());

  return i;
}

///////////////////////////////////////////////////////////////////////////////////////////


template class SingletonHandler<UniqueIndexMap,true>;
SingletonHandler<UniqueIndexMap,true> UniqueIndexBase::indices_map;

EMPTY_TEMPL_LIST bool StaticHandler<UniqueIndexBase>::staticdone=false;

///////////////////////////////////////////////////////////////////////////////////////////


#ifndef NO_UNIT_TEST

#define INDEX_TESTSIZE 5

class IndexTest : public UnitTest {

  // Test class
  class UniqueIndexTest : public UniqueIndex<UniqueIndexTest> {
   public:
    UniqueIndexTest(){};
    static const char* get_typename() {return "UniqueIndexTest";}
    static unsigned int get_max_instances() {return 0;}
  };

 public:
  IndexTest() : UnitTest("index") {}

 private:

  bool compare_and_report(int expected[INDEX_TESTSIZE], UniqueIndexTest* objs[INDEX_TESTSIZE], const char* txt) const {
    Log<UnitTest> odinlog(this,"compare_and_report");
    for(unsigned int i=0; i<INDEX_TESTSIZE; i++) {
      if(expected[i]>=0) {
        int returned=objs[i]->get_index();
        if(expected[i]!=returned) {
          ODINLOG(odinlog,errorLog) << txt << "[" << i << "]: expected/returned=" << expected[i] << "/" << returned << STD_endl;
          return true;
        }
      }
    }
    return false;
  }


  bool check() const {
    Log<UnitTest> odinlog(this,"check");

    UniqueIndexTest* objs[INDEX_TESTSIZE];

    for(unsigned int i=0; i<INDEX_TESTSIZE; i++) objs[i]=new UniqueIndexTest;

    int expected[]={0,1,2,3,4};
    if(compare_and_report(expected, objs, "alloc")) return false;


    // check whether 1st deleted slot is filled by new object
    delete objs[3];
    delete objs[1];

    objs[1]=new UniqueIndexTest;
    int expected2[]={0,1,2,-1,4};
    if(compare_and_report(expected2, objs, "realloc1")) return false;

    objs[3]=new UniqueIndexTest;
    if(compare_and_report(expected, objs, "realloc1")) return false;

    UniqueIndexTest* endobj=new UniqueIndexTest;
    unsigned int endobjindex_expected=INDEX_TESTSIZE;
    unsigned int endobjindex=endobj->get_index();
    if(endobjindex!=endobjindex_expected) {
      ODINLOG(odinlog,errorLog) << "endobjindex/_expected=" << endobjindex << "/" << endobjindex_expected << STD_endl;
      return false;
    }
    delete endobj;

    // Delete in reverse order and check again
    delete objs[1];
    delete objs[3];

    objs[1]=new UniqueIndexTest;
    objs[3]=new UniqueIndexTest;
    if(compare_and_report(expected, objs, "realloc2")) return false;


    // Delete begin and end indices
    delete objs[0];
    delete objs[INDEX_TESTSIZE-1];
    int expected3[]={-1,1,2,3,-1};
    if(compare_and_report(expected3, objs, "begin/end")) return false;

    // Re-create in reverse order
    objs[INDEX_TESTSIZE-1]=new UniqueIndexTest;
    int expected4[]={-1,1,2,3,0};
    if(compare_and_report(expected4, objs, "begin/end(realloc1)")) return false;


    objs[0]=new UniqueIndexTest;
    int expected5[]={4,1,2,3,0};
    if(compare_and_report(expected5, objs, "begin/end(realloc2)")) return false;



    for(unsigned int i=0; i<INDEX_TESTSIZE; i++) delete objs[i];
    return true;
  }

};

void alloc_IndexTest() {new IndexTest();} // create test instance
#endif