Skip to content

Commit 96fb4ca

Browse files
committed
Rewrite format_number_range
The previous code contained an unreachable instruction "next=true;" As I could not figure out where it belongs I ended up rewriting it, now using a lot less nesting and putting all the state into the iterator and a single start_number variable instead of several Booleans.
1 parent db3784f commit 96fb4ca

File tree

2 files changed

+44
-89
lines changed

2 files changed

+44
-89
lines changed

src/util/format_number_range.cpp

Lines changed: 43 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -10,107 +10,62 @@ Author: Daniel Kroening, [email protected]
1010
/// Format vector of numbers into a compressed range
1111

1212
#include <algorithm>
13-
#include <cassert>
13+
#include <sstream>
1414
#include <string>
1515

16+
#include "invariant.h"
17+
1618
#include "format_number_range.h"
1719

1820
/// create shorter representation for output
19-
/// \param parameters: vector of numbers
21+
/// \param input_numbers: vector of numbers
2022
/// \return string of compressed number range representation
21-
std::string format_number_range(std::vector<unsigned> &numbers)
23+
std::string format_number_range(const std::vector<unsigned> &input_numbers)
2224
{
23-
std::string number_range;
25+
PRECONDITION(!input_numbers.empty());
26+
27+
std::vector<unsigned> numbers(input_numbers);
2428
std::sort(numbers.begin(), numbers.end());
2529
unsigned end_number=numbers.back();
2630
if(numbers.front()==end_number)
27-
number_range=std::to_string(end_number); // only single number
28-
else
31+
return std::to_string(end_number); // only single number
32+
33+
std::stringstream number_range;
34+
35+
auto start_number = numbers.front();
36+
37+
for(std::vector<unsigned>::const_iterator it = numbers.begin();
38+
it != numbers.end();
39+
++it)
2940
{
30-
bool next=true;
31-
bool first=true;
32-
bool range=false;
33-
unsigned start_number=numbers.front();
34-
unsigned last_number=start_number;
41+
const auto number = *it;
42+
const auto next = std::next(it);
43+
44+
// advance one forward
45+
if(next != numbers.end() && *next <= number + 1)
46+
continue;
47+
48+
// end this block range
49+
if(start_number != numbers.front())
50+
number_range << ',';
3551

36-
for(const auto &number : numbers)
52+
if(number == start_number)
3753
{
38-
if(next)
39-
{
40-
next=false;
41-
start_number=number;
42-
last_number=number;
43-
}
44-
// advance one forward
45-
else
46-
{
47-
if(number==last_number+1 && !(number==end_number))
48-
{
49-
last_number++;
50-
if(last_number>start_number+1)
51-
range=true;
52-
}
53-
// end this block range
54-
else
55-
{
56-
if(first)
57-
first=false;
58-
else
59-
number_range+=",";
60-
if(last_number>start_number)
61-
{
62-
if(range)
63-
{
64-
if(number==end_number && number==last_number+1)
65-
number_range+=
66-
std::to_string(start_number)+"-"+std::to_string(end_number);
67-
else if(number==end_number)
68-
number_range+=
69-
std::to_string(start_number)+"-"+std::to_string(last_number)+
70-
","+std::to_string(end_number);
71-
else
72-
number_range+=
73-
std::to_string(start_number)+"-"+std::to_string(last_number);
74-
}
75-
else
76-
{
77-
if(number!=end_number)
78-
number_range+=
79-
std::to_string(start_number)+","+std::to_string(last_number);
80-
else
81-
{
82-
if(start_number+1==last_number && last_number+1==number)
83-
number_range+=
84-
std::to_string(start_number)+"-"+std::to_string(end_number);
85-
else
86-
number_range+=
87-
std::to_string(start_number)+
88-
","+std::to_string(last_number)+
89-
","+std::to_string(end_number);
90-
}
91-
}
92-
start_number=number;
93-
last_number=number;
94-
range=false;
95-
continue;
96-
}
97-
else
98-
{
99-
if(number!=end_number)
100-
number_range+=std::to_string(start_number);
101-
else
102-
number_range+=std::to_string(start_number)+","+
103-
std::to_string(end_number);
104-
start_number=number;
105-
last_number=number;
106-
range=false;
107-
continue; // already set next start number
108-
}
109-
next=true;
110-
}
111-
}
54+
number_range << number;
11255
}
56+
else if(number == start_number + 1)
57+
{
58+
number_range << start_number << ',' << number;
59+
}
60+
else
61+
{
62+
number_range << start_number << '-' << number;
63+
}
64+
65+
if(next != numbers.end())
66+
start_number = *next;
11367
}
114-
assert(!number_range.empty());
115-
return number_range;
68+
69+
CHECK_RETURN(!number_range.str().empty());
70+
return number_range.str();
11671
}

src/util/format_number_range.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@ Author: Daniel Kroening, [email protected]
1515
#include <string>
1616
#include <vector>
1717

18-
std::string format_number_range(std::vector<unsigned> &);
18+
std::string format_number_range(const std::vector<unsigned> &);
1919

2020
#endif // CPROVER_UTIL_FORMAT_NUMBER_RANGE_H

0 commit comments

Comments
 (0)