forked from Cdower/STEPxml
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathROSERange.h
135 lines (109 loc) · 2.88 KB
/
ROSERange.h
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
//Wrapper class for RoseCursor that implements C++ style iterators.
//Courtesy of Nathan West.
#pragma once
#include <iostream>
#include <iterator>
#include <string>
#include <rose.h>
template<class T>
class RoseRange
{
RoseDesign* design;
RoseTypePtr type;
public:
RoseRange(RoseDesign* design, RoseTypePtr type) :
design(design),
type(type)
{}
//C++ style iterator around a RoseCursor
class RoseIterator :
public std::iterator<std::bidirectional_iterator_tag, T>
{
RoseCursor cursor;
RoseRange* range;
T* current;
//ITERATOR IMPLEMENTATION
//Modeled after boost::iterator_facade
//http://www.boost.org/doc/libs/1_55_0/libs/iterator/doc/iterator_facade.html
//Get the current RoseObject
T& dereference() const
{
return *current;
}
//Compare to another iterator
bool equal(const RoseIterator& rhs) const
{
return current == rhs.current;
}
//This is what ROSE_CAST does under the hood. We cant use ROSE_CAST without the literal type name.
T* iter_rose_cast(RoseObject* object)
{
return static_cast<T*>(rose_cast(object, range->type));
}
//Increment iterator
void increment()
{
current = iter_rose_cast(cursor.next());
}
//Decrement iterator
void decrement()
{
current = iter_rose_cast(cursor.previous());
}
public:
//Begin constructor
RoseIterator(RoseRange* range) :
range(range)
{
//Set up domain and traversal
cursor.traverse(range->design);
cursor.domain(range->type->domain());
//Need initial increment to get the first next()
increment();
}
//End-of-range iterator is a null pointer
RoseIterator() :
range(0),
current(0)
{}
//Public interface uses the private implementation methods
//Comparison
bool operator ==(const RoseIterator& rhs) const { return equal(rhs); }
bool operator !=(const RoseIterator& rhs) const { return !equal(rhs); }
//Prefix operators (++it, --it)
RoseIterator& operator++() { increment(); return *this; }
RoseIterator& operator--() { decrement(); return *this; }
//Postfix operators (it++, it--)
RoseIterator operator++(int)
{
RoseIterator tmp = *this;
increment();
return tmp;
}
RoseIterator operator--(int)
{
RoseIterator tmp = *this;
decrement();
return tmp;
}
//Pointer operators
T& operator*() const { return dereference(); }
T* operator->() const { return &dereference(); }
//Direct access to the cursor. Could be useful.
RoseCursor& get_cursor() { return cursor; }
const RoseCursor& get_cursor() const { return cursor; }
//Explicit conversion to pointer
T* ptr() { return current; }
};
//Standard begin and end methods for getting iterators
RoseIterator begin()
{
return RoseIterator(this);
}
RoseIterator end()
{
return RoseIterator();
}
};
//Macro to create a RoseRange, for use in new-style for loops or STL algorithms
#define ROSE_RANGE(TYP, DESIGN) (RoseRange<TYP>((DESIGN), (ROSE_TYPE(TYP))))