Skip to content

Commit 25c7b47

Browse files
Merge pull request diffblue#93 from diffblue/nathan/feature/string_join-allow-string-constant
Updated string_join to allow string constant arguments
2 parents bf87420 + 267aa9f commit 25c7b47

File tree

5 files changed

+90
-34
lines changed

5 files changed

+90
-34
lines changed

src/taint-analysis/taint_summary_dump.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ dumper taint_sett::dump(const taint_tokent::named_tokenst &named_tokens) const
3636
ostr << "\u22A5";
3737
return;
3838
}
39-
std::string set_separator(" \u222A "),
40-
set_element_separator(", ");
39+
const char *set_separator(" \u222A "),
40+
*set_element_separator(", ");
4141
if(!tokens.empty() || !variables.empty())
4242
{
4343
ostr << "{ " << join(
@@ -401,13 +401,14 @@ bool taint_functions_for_dumping_taint_summary_in_htmlt::
401401
ostr << " and ";
402402
if(props.get_sink_conditions().size()>1U && set.size()>1U)
403403
ostr << " ( ";
404-
const taint_tokent::named_tokenst * const named_tokens_ptr=
405-
&named_tokens;
404+
const taint_tokent::named_tokenst &named_tokens=
405+
this->named_tokens;
406406
ostr << html_encoding()
407-
<< join(set | boost::adaptors::transformed(
408-
[named_tokens_ptr](const taint_subject_conditiont &cond)
409-
{ return cond.dump(*named_tokens_ptr); }),
410-
std::string(" or "));
407+
<< join(
408+
set | boost::adaptors::transformed(
409+
[&named_tokens] (const taint_subject_conditiont &cond)
410+
{ return cond.dump(named_tokens); }),
411+
" or ");
411412
if(props.get_sink_conditions().size()>1U && set.size()>1U)
412413
ostr << " ) ";
413414
}

src/util/string_join.h

Lines changed: 74 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,77 @@
1+
/*******************************************************************\
2+
3+
Module: String joiner
4+
5+
6+
7+
Purpose:
8+
To join multiple objects that can be piped to a stream into a list separated
9+
by a string provided by the user.
10+
11+
\*******************************************************************/
12+
113
#ifndef CPROVER__util__string_join
214
#define CPROVER__util__string_join
315

4-
516
#include <iterator>
617
#include <sstream>
718

8-
template<typename Str, typename It>
19+
20+
template<typename T>
21+
struct string_traitst final
22+
{
23+
typedef typename T::value_type char_typet;
24+
typedef typename T::traits_type traits_typet;
25+
typedef typename T::allocator_type allocator_typet;
26+
};
27+
28+
template<>
29+
struct string_traitst<const char *> final
30+
{
31+
typedef char char_typet;
32+
typedef typename std::char_traits<char> traits_typet;
33+
typedef typename std::allocator<char> allocator_typet;
34+
};
35+
36+
37+
template<typename Str, typename It, typename Str_Traits = string_traitst<Str>>
938
class joined_strings
1039
{
1140
private:
1241
const It begin, end;
1342
Str sep;
1443

1544
public:
16-
typedef typename Str::value_type char_type;
17-
typedef typename Str::traits_type traits_type;
18-
typedef typename Str::allocator_type allocator_type;
45+
typedef typename Str_Traits::char_typet char_typet;
46+
typedef typename Str_Traits::traits_typet traits_typet;
47+
typedef typename Str_Traits::allocator_typet allocator_typet;
48+
typedef
49+
typename std::basic_string<char_typet, traits_typet, allocator_typet>
50+
string_typet;
1951

2052
private:
21-
typedef std::basic_ostringstream<char_type, traits_type, allocator_type>
22-
ostringstream_type;
53+
typedef std::basic_ostringstream<char_typet, traits_typet, allocator_typet>
54+
ostringstream_typet;
2355

2456
public:
25-
joined_strings(It begin, const It end, const Str &sep)
26-
: begin(begin), end(end), sep(sep)
57+
template<typename It_In, typename Str_In>
58+
joined_strings(It_In &&begin, It_In &&end, Str_In &&sep)
59+
: begin(std::forward<It_In>(begin)),
60+
end(std::forward<It_In>(end)),
61+
sep(std::forward<Str_In>(sep))
2762
{
2863
}
2964

30-
operator Str() const
65+
operator string_typet() const
3166
{
32-
ostringstream_type result;
67+
ostringstream_typet result;
3368
result << *this;
3469
return result.str();
3570
}
3671

37-
template<typename ostream_type>
38-
friend ostream_type& operator<<(
39-
ostream_type &ostr, const joined_strings<Str, It> &joined)
72+
template<typename ostream_typet>
73+
friend ostream_typet& operator<<(
74+
ostream_typet &ostr, const joined_strings<Str, It> &joined)
4075
{
4176
It it = joined.begin;
4277
if(it!=joined.end)
@@ -50,12 +85,24 @@ class joined_strings
5085
}
5186
};
5287

88+
5389
template<typename Str, typename It>
54-
inline joined_strings<Str, It> join(It begin, const It end, const Str &sep)
90+
inline joined_strings<Str, It> join(It begin, It end, const Str &sep)
5591
{
56-
return joined_strings<Str, It>(begin, end, sep);
92+
return joined_strings<Str, It>(std::move(begin), std::move(end), sep);
5793
}
5894

95+
template<typename It>
96+
inline joined_strings<const char *, It> join(
97+
It begin, It end, const char *sep)
98+
{
99+
return joined_strings<const char *, It>(
100+
std::move(begin),
101+
std::move(end),
102+
sep);
103+
}
104+
105+
59106
template<typename Str, typename Container>
60107
class joined_strings_container
61108
: public joined_strings<Str, typename Container::const_iterator>
@@ -64,10 +111,11 @@ class joined_strings_container
64111
Container container;
65112

66113
public:
67-
joined_strings_container(const Container &container, const Str &sep)
114+
template<typename Container_In, typename Str_In>
115+
joined_strings_container(Container_In &&container, Str_In &&sep)
68116
: joined_strings<Str, typename Container::const_iterator>(
69-
container.begin(), container.end(), sep),
70-
container(container)
117+
container.begin(), container.end(), std::forward<Str_In>(sep)),
118+
container(std::forward<Container_In>(container))
71119
{
72120
}
73121
};
@@ -79,5 +127,12 @@ inline joined_strings_container<Str, Container> join(
79127
return joined_strings_container<Str, Container>(container, sep);
80128
}
81129

130+
template<typename Container>
131+
inline joined_strings_container<const char *, Container> join(
132+
const Container &container, const char *sep)
133+
{
134+
return joined_strings_container<const char *, Container>(container, sep);
135+
}
136+
82137

83138
#endif

unit/range_union/main.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ int main()
2323
<< "Testing range_union" << indentation.add(2) << endl_ind;
2424
std::vector<int> a = { 2, 4, 8 },
2525
b = { 3, 4, 9 };
26-
std::cout << join(a, std::string(", ")) << " union itself = "
27-
<< join(range_union(a, a), std::string(", ")) << endl_ind;
26+
std::cout << join(a, ", ") << " union itself = "
27+
<< join(range_union(a, a), ", ") << endl_ind;
2828
test_assert(boost::size(range_union(a, a)) == 3, "Exact duplicate collapses");
29-
std::cout << join(a, std::string(", "))
30-
<< " union " << join(b, std::string(", "))
31-
<< " = " << join(range_union(a, b), std::string(", ")) << endl_ind;
29+
std::cout << join(a, ", ")
30+
<< " union " << join(b, ", ")
31+
<< " = " << join(range_union(a, b), ", ") << endl_ind;
3232
test_assert(boost::size(range_union(a, b)) == 5, "Duplicates are removed");
3333
test_assert(boost::size(range_union(b, a)) == 5, "Commutative");
3434
std::vector<std::string> strs = { "hi", "lo" };

unit/serialization/json_map_serializer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ void test_json_map_serializer()
6868
boost::sort(expected_keys);
6969
boost::push_back(actual_keys, serializer.keys());
7070
std::cout
71-
<< "Checking keys: " << join(actual_keys, std::string(", ")) << endl_ind;
71+
<< "Checking keys: " << join(actual_keys, ", ") << endl_ind;
7272
test_assert(
7373
expected_keys == actual_keys,
7474
"Keys returns sorted expected keys");

unit/serialization/virtual_map.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ void test_virtual_map()
105105
boost::sort(expected_keys);
106106
boost::push_back(actual_keys, map.keys());
107107
std::cout
108-
<< "Checking keys: " << join(actual_keys, std::string(", ")) << endl_ind;
108+
<< "Checking keys: " << join(actual_keys, ", ") << endl_ind;
109109
test_assert(
110110
expected_keys == actual_keys,
111111
"Keys returns sorted expected keys");

0 commit comments

Comments
 (0)