Skip to content

Commit 93495c3

Browse files
committed
Reduce unnecessary uses of std::list
1 parent 863e09e commit 93495c3

7 files changed

+54
-78
lines changed

pyc_code.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33

44
#include "pyc_sequence.h"
55
#include "pyc_string.h"
6+
#include <set>
67

78
class PycCode : public PycObject {
89
public:
9-
typedef std::list<PycRef<PycString> > globals_t;
10+
typedef std::set<PycRef<PycString>> globals_t;
1011
enum CodeFlags {
1112
CO_OPTIMIZED = 0x1,
1213
CO_NEWLOCALS = 0x2,
@@ -76,8 +77,7 @@ class PycCode : public PycObject {
7677

7778
void markGlobal(PycRef<PycString> varname)
7879
{
79-
m_globalsUsed.push_back(varname);
80-
m_globalsUsed.unique();
80+
m_globalsUsed.emplace(std::move(varname));
8181
}
8282

8383
private:

pyc_module.cpp

+4-16
Original file line numberDiff line numberDiff line change
@@ -235,26 +235,14 @@ void PycModule::loadFromMarshalledFile(const char* filename, int major, int mino
235235

236236
PycRef<PycString> PycModule::getIntern(int ref) const
237237
{
238-
if (ref < 0)
238+
if (ref < 0 || (size_t)ref >= m_interns.size())
239239
throw std::out_of_range("Intern index out of range");
240-
241-
auto it = m_interns.cbegin();
242-
while (ref-- && it != m_interns.cend())
243-
++it;
244-
if (it == m_interns.cend())
245-
throw std::out_of_range("Intern index out of range");
246-
return *it;
240+
return m_interns[(size_t)ref];
247241
}
248242

249243
PycRef<PycObject> PycModule::getRef(int ref) const
250244
{
251-
if (ref < 0)
252-
throw std::out_of_range("Ref index out of range");
253-
254-
auto it = m_refs.cbegin();
255-
while (ref-- && it != m_refs.cend())
256-
++it;
257-
if (it == m_refs.cend())
245+
if (ref < 0 || (size_t)ref >= m_refs.size())
258246
throw std::out_of_range("Ref index out of range");
259-
return *it;
247+
return m_refs[(size_t)ref];
260248
}

pyc_module.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#define _PYC_MODULE_H
33

44
#include "pyc_code.h"
5-
#include <list>
5+
#include <vector>
66

77
enum PycMagic {
88
MAGIC_1_0 = 0x00999902,
@@ -64,10 +64,10 @@ class PycModule {
6464

6565
PycRef<PycCode> code() const { return m_code; }
6666

67-
void intern(PycRef<PycString> str) { m_interns.push_back(str); }
67+
void intern(PycRef<PycString> str) { m_interns.emplace_back(std::move(str)); }
6868
PycRef<PycString> getIntern(int ref) const;
6969

70-
void refObject(PycRef<PycObject> str) { m_refs.push_back(str); }
70+
void refObject(PycRef<PycObject> obj) { m_refs.emplace_back(std::move(obj)); }
7171
PycRef<PycObject> getRef(int ref) const;
7272

7373
static bool isSupportedVersion(int major, int minor);
@@ -80,8 +80,8 @@ class PycModule {
8080
bool m_unicode;
8181

8282
PycRef<PycCode> m_code;
83-
std::list<PycRef<PycString> > m_interns;
84-
std::list<PycRef<PycObject> > m_refs;
83+
std::vector<PycRef<PycString>> m_interns;
84+
std::vector<PycRef<PycObject>> m_refs;
8585
};
8686

8787
#endif

pyc_numeric.cpp

+8-5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ void PycInt::load(PycData* stream, PycModule*)
1818
void PycLong::load(PycData* stream, PycModule*)
1919
{
2020
if (type() == TYPE_INT64) {
21+
m_value.reserve(4);
2122
int lo = stream->get32();
2223
int hi = stream->get32();
2324
m_value.push_back((lo ) & 0xFFFF);
@@ -28,6 +29,7 @@ void PycLong::load(PycData* stream, PycModule*)
2829
} else {
2930
m_size = stream->get32();
3031
int actualSize = m_size >= 0 ? m_size : -m_size;
32+
m_value.reserve(actualSize);
3133
for (int i=0; i<actualSize; i++)
3234
m_value.push_back(stream->get16());
3335
}
@@ -41,9 +43,9 @@ bool PycLong::isEqual(PycRef<PycObject> obj) const
4143
PycRef<PycLong> longObj = obj.cast<PycLong>();
4244
if (m_size != longObj->m_size)
4345
return false;
44-
std::list<int>::const_iterator it1 = m_value.begin();
45-
std::list<int>::const_iterator it2 = longObj->m_value.begin();
46-
while (it1 != m_value.end()) {
46+
auto it1 = m_value.cbegin();
47+
auto it2 = longObj->m_value.cbegin();
48+
while (it1 != m_value.cend()) {
4749
if (*it1 != *it2)
4850
return false;
4951
++it1, ++it2;
@@ -60,7 +62,8 @@ std::string PycLong::repr() const
6062
return "0x0L";
6163

6264
// Realign to 32 bits, since Python uses only 15
63-
std::list<unsigned> bits;
65+
std::vector<unsigned> bits;
66+
bits.reserve((m_value.size() + 1) / 2);
6467
int shift = 0, temp = 0;
6568
for (auto bit : m_value) {
6669
temp |= unsigned(bit & 0xFFFF) << shift;
@@ -83,7 +86,7 @@ std::string PycLong::repr() const
8386
*aptr++ = '0';
8487
*aptr++ = 'x';
8588

86-
std::list<unsigned>::const_reverse_iterator iter = bits.rbegin();
89+
auto iter = bits.crbegin();
8790
aptr += snprintf(aptr, 9, "%X", *iter++);
8891
while (iter != bits.rend())
8992
aptr += snprintf(aptr, 9, "%08X", *iter++);

pyc_numeric.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
#include "pyc_object.h"
55
#include "data.h"
6-
#include <list>
6+
#include <vector>
77
#include <string>
88

99
class PycInt : public PycObject {
@@ -35,13 +35,13 @@ class PycLong : public PycObject {
3535
void load(class PycData* stream, class PycModule* mod) override;
3636

3737
int size() const { return m_size; }
38-
const std::list<int>& value() const { return m_value; }
38+
const std::vector<int>& value() const { return m_value; }
3939

4040
std::string repr() const;
4141

4242
private:
4343
int m_size;
44-
std::list<int> m_value;
44+
std::vector<int> m_value;
4545
};
4646

4747
class PycFloat : public PycObject {

pyc_sequence.cpp

+25-39
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ bool PycTuple::isEqual(PycRef<PycObject> obj) const
2424
PycRef<PycTuple> tupleObj = obj.cast<PycTuple>();
2525
if (m_size != tupleObj->m_size)
2626
return false;
27-
value_t::const_iterator it1 = m_values.begin();
28-
value_t::const_iterator it2 = tupleObj->m_values.begin();
29-
while (it1 != m_values.end()) {
27+
auto it1 = m_values.cbegin();
28+
auto it2 = tupleObj->m_values.cbegin();
29+
while (it1 != m_values.cend()) {
3030
if (!(*it1)->isEqual(*it2))
3131
return false;
3232
++it1, ++it2;
@@ -51,30 +51,16 @@ bool PycList::isEqual(PycRef<PycObject> obj) const
5151
PycRef<PycList> listObj = obj.cast<PycList>();
5252
if (m_size != listObj->m_size)
5353
return false;
54-
value_t::const_iterator it1 = m_values.begin();
55-
value_t::const_iterator it2 = listObj->m_values.begin();
56-
while (it1 != m_values.end()) {
54+
auto it1 = m_values.cbegin();
55+
auto it2 = listObj->m_values.cbegin();
56+
while (it1 != m_values.cend()) {
5757
if (!(*it1)->isEqual(*it2))
5858
return false;
5959
++it1, ++it2;
6060
}
6161
return true;
6262
}
6363

64-
PycRef<PycObject> PycList::get(int idx) const
65-
{
66-
if (idx < 0)
67-
throw std::out_of_range("List index out of range");
68-
69-
value_t::const_iterator it = m_values.begin();
70-
while (idx-- && it != m_values.end())
71-
++it;
72-
if (it == m_values.end())
73-
throw std::out_of_range("List index out of range");
74-
return *it;
75-
}
76-
77-
7864

7965
/* PycDict */
8066
void PycDict::load(PycData* stream, PycModule* mod)
@@ -99,17 +85,17 @@ bool PycDict::isEqual(PycRef<PycObject> obj) const
9985
if (m_size != dictObj->m_size)
10086
return false;
10187

102-
key_t::const_iterator ki1 = m_keys.begin();
103-
key_t::const_iterator ki2 = dictObj->m_keys.begin();
104-
while (ki1 != m_keys.end()) {
88+
auto ki1 = m_keys.cbegin();
89+
auto ki2 = dictObj->m_keys.cbegin();
90+
while (ki1 != m_keys.cend()) {
10591
if (!(*ki1)->isEqual(*ki2))
10692
return false;
10793
++ki1, ++ki2;
10894
}
10995

110-
value_t::const_iterator vi1 = m_values.begin();
111-
value_t::const_iterator vi2 = dictObj->m_values.begin();
112-
while (vi1 != m_values.end()) {
96+
auto vi1 = m_values.cbegin();
97+
auto vi2 = dictObj->m_values.cbegin();
98+
while (vi1 != m_values.cend()) {
11399
if (!(*vi1)->isEqual(*vi2))
114100
return false;
115101
++vi1, ++vi2;
@@ -119,25 +105,25 @@ bool PycDict::isEqual(PycRef<PycObject> obj) const
119105

120106
PycRef<PycObject> PycDict::get(PycRef<PycObject> key) const
121107
{
122-
key_t::const_iterator ki = m_keys.begin();
123-
value_t::const_iterator vi = m_values.begin();
124-
while (ki != m_keys.end()) {
108+
auto ki = m_keys.cbegin();
109+
auto vi = m_values.cbegin();
110+
while (ki != m_keys.cend()) {
125111
if ((*ki)->isEqual(key))
126112
return *vi;
127113
++ki, ++vi;
128114
}
129-
return NULL; // Disassembly shouldn't get non-existant keys
115+
return NULL; // Disassembly shouldn't get non-existent keys
130116
}
131117

132118
PycRef<PycObject> PycDict::get(int idx) const
133119
{
134120
if (idx < 0)
135121
throw std::out_of_range("Dict index out of range");
136122

137-
value_t::const_iterator it = m_values.begin();
138-
while (idx-- && it != m_values.end())
123+
auto it = m_values.cbegin();
124+
while (idx-- && it != m_values.cend())
139125
++it;
140-
if (it == m_values.end())
126+
if (it == m_values.cend())
141127
throw std::out_of_range("Dict index out of range");
142128
return *it;
143129
}
@@ -159,9 +145,9 @@ bool PycSet::isEqual(PycRef<PycObject> obj) const
159145
PycRef<PycSet> setObj = obj.cast<PycSet>();
160146
if (m_size != setObj->m_size)
161147
return false;
162-
value_t::const_iterator it1 = m_values.begin();
163-
value_t::const_iterator it2 = setObj->m_values.begin();
164-
while (it1 != m_values.end()) {
148+
auto it1 = m_values.cbegin();
149+
auto it2 = setObj->m_values.cbegin();
150+
while (it1 != m_values.cend()) {
165151
if (!(*it1)->isEqual(*it2))
166152
return false;
167153
++it1, ++it2;
@@ -174,10 +160,10 @@ PycRef<PycObject> PycSet::get(int idx) const
174160
if (idx < 0)
175161
throw std::out_of_range("Set index out of range");
176162

177-
value_t::const_iterator it = m_values.begin();
178-
while (idx-- && it != m_values.end())
163+
auto it = m_values.cbegin();
164+
while (idx-- && it != m_values.cend())
179165
++it;
180-
if (it == m_values.end())
166+
if (it == m_values.cend())
181167
throw std::out_of_range("Set index out of range");
182168
return *it;
183169
}

pyc_sequence.h

+6-7
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
#include "pyc_object.h"
55
#include <vector>
6-
#include <list>
76
#include <set>
87

98
class PycSequence : public PycObject {
@@ -19,7 +18,7 @@ class PycSequence : public PycObject {
1918

2019
class PycTuple : public PycSequence {
2120
public:
22-
typedef std::vector<PycRef<PycObject> > value_t;
21+
typedef std::vector<PycRef<PycObject>> value_t;
2322

2423
PycTuple(int type = TYPE_TUPLE) : PycSequence(type) { }
2524

@@ -36,7 +35,7 @@ class PycTuple : public PycSequence {
3635

3736
class PycList : public PycSequence {
3837
public:
39-
typedef std::list<PycRef<PycObject> > value_t;
38+
typedef std::vector<PycRef<PycObject>> value_t;
4039

4140
PycList(int type = TYPE_LIST) : PycSequence(type) { }
4241

@@ -45,16 +44,16 @@ class PycList : public PycSequence {
4544
void load(class PycData* stream, class PycModule* mod) override;
4645

4746
const value_t& values() const { return m_values; }
48-
PycRef<PycObject> get(int idx) const override;
47+
PycRef<PycObject> get(int idx) const override { return m_values.at(idx); }
4948

5049
private:
5150
value_t m_values;
5251
};
5352

5453
class PycDict : public PycSequence {
5554
public:
56-
typedef std::list<PycRef<PycObject> > key_t;
57-
typedef std::list<PycRef<PycObject> > value_t;
55+
typedef std::vector<PycRef<PycObject>> key_t;
56+
typedef std::vector<PycRef<PycObject>> value_t;
5857

5958
PycDict(int type = TYPE_DICT) : PycSequence(type) { }
6059

@@ -75,7 +74,7 @@ class PycDict : public PycSequence {
7574

7675
class PycSet : public PycSequence {
7776
public:
78-
typedef std::set<PycRef<PycObject> > value_t;
77+
typedef std::set<PycRef<PycObject>> value_t;
7978

8079
PycSet(int type = TYPE_SET) : PycSequence(type) { }
8180

0 commit comments

Comments
 (0)