Skip to content

Commit 1116de5

Browse files
authored
Merge pull request #495 from Ghabry/stringview
Migrate from string view lite to std::string_view
2 parents 2296b0b + 01b63c6 commit 1116de5

33 files changed

Lines changed: 320 additions & 1871 deletions

CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,6 @@ set(LCF_HEADERS
295295
src/generated/lcf/rpg/trooppagecondition.h
296296
src/generated/lcf/rpg/variable.h
297297
src/lcf/third_party/span.h
298-
src/lcf/third_party/string_view.h
299298
)
300299

301300
set(LCF_SUPPORT_INI 0)

Makefile.am

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,7 @@ lcfrpginclude_HEADERS = \
327327
src/generated/lcf/rpg/variable.h
328328

329329
lcfthirdpartyinclude_HEADERS = \
330-
src/lcf/third_party/span.h \
331-
src/lcf/third_party/string_view.h
330+
src/lcf/third_party/span.h
332331

333332
nodist_lcfinclude_HEADERS = src/lcf/config.h
334333

@@ -344,6 +343,7 @@ test_runner_SOURCES = \
344343
tests/doctest.h \
345344
tests/enum_tags.cpp \
346345
tests/flag_set.cpp \
346+
tests/ini.cpp \
347347
tests/test_main.cpp \
348348
tests/time_stamp.cpp \
349349
tests/span.cpp \

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ See the file [COPYING] for copying conditions.
117117
liblcf includes code of the following 3rd party software:
118118

119119
- [inih] under New BSD license.
120-
- [string-view-lite] and [span-lite] under Boost Software License, Version 1.0.
120+
- [span-lite] under Boost Software License, Version 1.0.
121121

122122
See the source code comment headers for license details.
123123

generator/csv/functions.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
Structure,Method,Static,Headers
22
Actor,void Setup(bool is2k3),f,
33
Parameters,void Setup(int final_level),f,
4-
Terms,"std::string TermOrDefault(const DBString& db_term, StringView default_term)",t,
4+
Terms,"std::string TermOrDefault(const DBString& db_term, std::string_view default_term)",t,

src/generated/lcf/rpg/terms.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ namespace rpg {
2828
// Sentinel name used to denote that the default hardcoded term should be used.
2929
static constexpr const char* kDefaultTerm = "default_term";
3030

31-
static std::string TermOrDefault(const DBString& db_term, StringView default_term);
31+
static std::string TermOrDefault(const DBString& db_term, std::string_view default_term);
3232
DBString encounter;
3333
DBString special_combat;
3434
DBString escape_success;

src/inireader.cpp

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,13 @@
3434
#include <cstdlib>
3535
#include <cstring>
3636
#include <istream>
37+
#include <charconv>
3738
#include <ini.h>
3839
#include "lcf/inireader.h"
3940

4041
namespace lcf {
4142

42-
INIReader::INIReader(const std::string& filename)
43+
INIReader::INIReader(std::string filename)
4344
{
4445
_error = ini_parse(filename.c_str(), ValueHandler, this);
4546
}
@@ -100,41 +101,50 @@ int INIReader::ParseError() const
100101
return _error;
101102
}
102103

103-
std::string INIReader::Get(const std::string& section, const std::string& name, const std::string& default_value) const
104+
std::string_view INIReader::Get(std::string_view section, std::string_view name, std::string_view default_value) const
104105
{
105106
std::string key = MakeKey(section, name);
106-
// Use _values.find() here instead of _values.at() to support pre C++11 compilers
107-
return _values.count(key) ? _values.find(key)->second : default_value;
107+
108+
auto it = _values.find(key);
109+
if (it == _values.end()) {
110+
return default_value;
111+
}
112+
return it->second;
108113
}
109114

110-
std::string INIReader::GetString(const std::string& section, const std::string& name, const std::string& default_value) const
115+
std::string_view INIReader::GetString(std::string_view section, std::string_view name, std::string_view default_value) const
111116
{
112-
const std::string str = Get(section, name, "");
117+
auto str = Get(section, name, "");
113118
return str.empty() ? default_value : str;
114119
}
115120

116-
long INIReader::GetInteger(const std::string& section, const std::string& name, long default_value) const
121+
long INIReader::GetInteger(std::string_view section, std::string_view name, long default_value) const
117122
{
118-
std::string valstr = Get(section, name, "");
119-
const char* value = valstr.c_str();
120-
char* end;
121-
// This parses "1234" (decimal) and also "0x4D2" (hex)
122-
long n = strtol(value, &end, 0);
123-
return end > value ? n : default_value;
123+
std::string_view valstr = Get(section, name, "");
124+
long n;
125+
auto ec = std::from_chars(valstr.data(), valstr.data() + valstr.size(), n).ec;
126+
return ec == std::errc() ? n : default_value;
124127
}
125128

126-
double INIReader::GetReal(const std::string& section, const std::string& name, double default_value) const
129+
double INIReader::GetReal(std::string_view section, std::string_view name, double default_value) const
127130
{
128-
std::string valstr = Get(section, name, "");
131+
std::string valstr = std::string(Get(section, name, ""));
129132
const char* value = valstr.c_str();
130133
char* end;
131134
double n = strtod(value, &end);
132135
return end > value ? n : default_value;
136+
/*
137+
// FIXME: std::from_chars<double> not supported by clang and old g++ versions
138+
std::string_view valstr = Get(section, name, "");
139+
double n;
140+
auto ec = std::from_chars(valstr.data(), valstr.data() + valstr.size(), n).ec;
141+
return ec == std::errc() ? n : default_value;
142+
*/
133143
}
134144

135-
bool INIReader::GetBoolean(const std::string& section, const std::string& name, bool default_value) const
145+
bool INIReader::GetBoolean(std::string_view section, std::string_view name, bool default_value) const
136146
{
137-
std::string valstr = Get(section, name, "");
147+
auto valstr = std::string(Get(section, name, ""));
138148
// Convert to lower case to make string comparisons case-insensitive
139149
std::transform(valstr.begin(), valstr.end(), valstr.begin(), ::tolower);
140150
if (valstr == "true" || valstr == "yes" || valstr == "on" || valstr == "1")
@@ -145,15 +155,15 @@ bool INIReader::GetBoolean(const std::string& section, const std::string& name,
145155
return default_value;
146156
}
147157

148-
bool INIReader::HasValue(const std::string& section, const std::string& name) const
158+
bool INIReader::HasValue(std::string_view section, std::string_view name) const
149159
{
150160
std::string key = MakeKey(section, name);
151-
return _values.count(key);
161+
return _values.find(key) != _values.end();
152162
}
153163

154-
std::string INIReader::MakeKey(const std::string& section, const std::string& name)
164+
std::string INIReader::MakeKey(std::string_view section, std::string_view name)
155165
{
156-
std::string key = section + "=" + name;
166+
std::string key = std::string(section) + "=" + std::string(name);
157167
// Convert to lower case to make section/name lookups case-insensitive
158168
std::transform(key.begin(), key.end(), key.begin(), ::tolower);
159169
return key;
@@ -164,9 +174,15 @@ int INIReader::ValueHandler(void* user, const char* section, const char* name,
164174
{
165175
INIReader* reader = static_cast<INIReader*>(user);
166176
std::string key = MakeKey(section, name);
167-
if (reader->_values[key].size() > 0)
168-
reader->_values[key] += "\n";
169-
reader->_values[key] += value;
177+
178+
auto [it, inserted] = reader->_values.try_emplace(key, value);
179+
180+
if (!inserted) {
181+
// Key is duplicated
182+
it->second += "\n";
183+
it->second += value;
184+
}
185+
170186
return 1;
171187
}
172188

src/lcf/context.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ namespace lcf {
1919
*/
2020
struct ContextNameBase {
2121
/** Constructor */
22-
constexpr ContextNameBase(StringView n, int i) : name(n), index(i) {}
22+
constexpr ContextNameBase(std::string_view n, int i) : name(n), index(i) {}
2323

2424
/** Name of the enumerated field */
25-
StringView name;
25+
std::string_view name;
2626

2727
/** Array index when the object is part of a list (-1 when not) */
2828
int index = -1;
@@ -38,7 +38,7 @@ struct ContextStructBase : ContextNameBase {
3838
using StructType_t = StructType;
3939

4040
/** Constructor */
41-
constexpr ContextStructBase(StringView n, int i, StructType_t* o)
41+
constexpr ContextStructBase(std::string_view n, int i, StructType_t* o)
4242
: ContextNameBase(n, i), obj(o) {}
4343

4444
/** Object instance (cast to appropriate RPG-type */
@@ -58,7 +58,7 @@ struct Context : ContextStructBase<StructType> {
5858
/** The type of the parent context */
5959
using ParentCtxType_t = ParentCtxType;
6060

61-
constexpr Context(StringView n, int i, StructType* o, const ParentCtxType_t* pctx)
61+
constexpr Context(std::string_view n, int i, StructType* o, const ParentCtxType_t* pctx)
6262
: ContextStructBase<StructType>{n, i, o}, parent(pctx) {}
6363

6464
/** Context of the parent (nullptr when no parent) */

src/lcf/dbstring.h

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,9 @@
1414
#include <iterator>
1515
#include <cstdint>
1616
#include <cstring>
17-
#include <limits>
1817
#include <algorithm>
1918
#include <ostream>
2019

21-
#include "lcf/string_view.h"
2220
#include "lcf/dbarrayalloc.h"
2321

2422
namespace lcf {
@@ -43,17 +41,17 @@ class DBString {
4341
static constexpr size_type npos = size_type(-1);
4442

4543
constexpr DBString() = default;
46-
explicit DBString(StringView s) : _storage(construct_sv(s.data(), s.size())) {}
44+
explicit DBString(std::string_view s) : _storage(construct_sv(s.data(), s.size())) {}
4745
explicit DBString(const std::string& s) : _storage(construct_z(s.c_str(), s.size())) {}
4846

4947
// Explicit construct for general const char*
50-
explicit DBString(const char* s) : DBString(StringView(s)) {}
48+
explicit DBString(const char* s) : DBString(std::string_view(s)) {}
5149
// Implicit constructor to capture string literals
5250
template <size_t N>
5351
DBString(const char(&literal)[N]) : _storage(construct_z(literal, N - 1)) {}
54-
DBString(const char* s, size_t len) : DBString(StringView(s, len)) {}
52+
DBString(const char* s, size_t len) : DBString(std::string_view(s, len)) {}
5553

56-
DBString(const DBString& o) : DBString(StringView(o)) {}
54+
DBString(const DBString& o) : DBString(std::string_view(o)) {}
5755
DBString(DBString&& o) noexcept { swap(o); }
5856

5957
DBString& operator=(const DBString&);
@@ -66,7 +64,7 @@ class DBString {
6664
~DBString() { destroy(); }
6765

6866
explicit operator std::string() const { return std::string(data(), size()); }
69-
operator StringView() const { return StringView(data(), size()); }
67+
operator std::string_view() const { return std::string_view(data(), size()); }
7068

7169
char& operator[](size_type i) { return data()[i]; }
7270
char operator[](size_type i) const { return data()[i]; }
@@ -123,21 +121,21 @@ inline std::string ToString(const DBString& s) {
123121
}
124122

125123
#define LCF_DBSTRING_MAKE_CMP_OPS(LTYPE, RTYPE) \
126-
inline bool operator==(LTYPE l, RTYPE r) { return StringView(l) == StringView(r); }\
127-
inline bool operator!=(LTYPE l, RTYPE r) { return StringView(l) != StringView(r); }\
128-
inline bool operator<(LTYPE l, RTYPE r) { return StringView(l) < StringView(r); }\
129-
inline bool operator>(LTYPE l, RTYPE r) { return StringView(l) > StringView(r); }\
130-
inline bool operator<=(LTYPE l, RTYPE r) { return StringView(l) <= StringView(r); }\
131-
inline bool operator>=(LTYPE l, RTYPE r) { return StringView(l) >= StringView(r); }\
124+
inline bool operator==(LTYPE l, RTYPE r) { return std::string_view(l) == std::string_view(r); }\
125+
inline bool operator!=(LTYPE l, RTYPE r) { return std::string_view(l) != std::string_view(r); }\
126+
inline bool operator<(LTYPE l, RTYPE r) { return std::string_view(l) < std::string_view(r); }\
127+
inline bool operator>(LTYPE l, RTYPE r) { return std::string_view(l) > std::string_view(r); }\
128+
inline bool operator<=(LTYPE l, RTYPE r) { return std::string_view(l) <= std::string_view(r); }\
129+
inline bool operator>=(LTYPE l, RTYPE r) { return std::string_view(l) >= std::string_view(r); }\
132130

133131
LCF_DBSTRING_MAKE_CMP_OPS(const DBString&, const DBString&);
134-
LCF_DBSTRING_MAKE_CMP_OPS(StringView, const DBString&);
135-
LCF_DBSTRING_MAKE_CMP_OPS(const DBString&, StringView);
132+
LCF_DBSTRING_MAKE_CMP_OPS(std::string_view, const DBString&);
133+
LCF_DBSTRING_MAKE_CMP_OPS(const DBString&, std::string_view);
136134
LCF_DBSTRING_MAKE_CMP_OPS(const char*, const DBString&);
137135
LCF_DBSTRING_MAKE_CMP_OPS(const DBString&, const char*);
138136

139137
inline std::ostream& operator<<(std::ostream& os, const DBString& s) {
140-
os << StringView(s);
138+
os << std::string_view(s);
141139
return os;
142140
}
143141

@@ -147,7 +145,7 @@ namespace std {
147145

148146
template <> struct hash<lcf::DBString> {
149147
size_t operator()(const lcf::DBString& s) const {
150-
return std::hash<lcf::StringView>()(lcf::StringView(s));
148+
return std::hash<std::string_view>()(std::string_view(s));
151149
}
152150
};
153151

src/lcf/encoder.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class Encoder {
4545

4646
bool IsOk() const;
4747

48-
const std::string& GetEncoding() const;
48+
std::string_view GetEncoding() const;
4949
private:
5050
#if LCF_SUPPORT_ICU
5151
void Init();
@@ -67,7 +67,7 @@ class Encoder {
6767
};
6868

6969

70-
inline const std::string& Encoder::GetEncoding() const {
70+
inline std::string_view Encoder::GetEncoding() const {
7171
return _encoding;
7272
}
7373

src/lcf/inireader.h

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@
3232
#ifndef LCF_INIREADER_H
3333
#define LCF_INIREADER_H
3434

35-
#include <map>
35+
#include <unordered_map>
3636
#include <string>
37+
#include <string_view>
3738

3839
namespace lcf {
3940

@@ -44,7 +45,7 @@ class INIReader
4445
public:
4546
// Construct INIReader and parse given filename. See ini.h for more info
4647
// about the parsing.
47-
explicit INIReader(const std::string& filename);
48+
explicit INIReader(std::string filename);
4849

4950
// Construct INIReader and parse given stream. See ini.h for more info
5051
// about the parsing.
@@ -56,35 +57,35 @@ class INIReader
5657
int ParseError() const;
5758

5859
// Get a string value from INI file, returning default_value if not found.
59-
std::string Get(const std::string& section, const std::string& name,
60-
const std::string& default_value) const;
60+
std::string_view Get(std::string_view section, std::string_view name,
61+
std::string_view default_value) const;
6162

6263
// Get a string value from INI file, returning default_value if not found,
6364
// empty, or contains only whitespace.
64-
std::string GetString(const std::string& section, const std::string& name,
65-
const std::string& default_value) const;
65+
std::string_view GetString(std::string_view section, std::string_view name,
66+
std::string_view default_value) const;
6667

6768
// Get an integer (long) value from INI file, returning default_value if
6869
// not found or not a valid integer (decimal "1234", "-1234", or hex "0x4d2").
69-
long GetInteger(const std::string& section, const std::string& name, long default_value) const;
70+
long GetInteger(std::string_view section, std::string_view name, long default_value) const;
7071

7172
// Get a real (floating point double) value from INI file, returning
7273
// default_value if not found or not a valid floating point value
7374
// according to strtod().
74-
double GetReal(const std::string& section, const std::string& name, double default_value) const;
75+
double GetReal(std::string_view section, std::string_view name, double default_value) const;
7576

7677
// Get a boolean value from INI file, returning default_value if not found or if
7778
// not a valid true/false value. Valid true values are "true", "yes", "on", "1",
7879
// and valid false values are "false", "no", "off", "0" (not case sensitive).
79-
bool GetBoolean(const std::string& section, const std::string& name, bool default_value) const;
80+
bool GetBoolean(std::string_view section, std::string_view name, bool default_value) const;
8081

8182
// Return true if a value exists with the given section and field names.
82-
bool HasValue(const std::string& section, const std::string& name) const;
83+
bool HasValue(std::string_view section, std::string_view name) const;
8384

8485
private:
8586
int _error;
86-
std::map<std::string, std::string> _values;
87-
static std::string MakeKey(const std::string& section, const std::string& name);
87+
std::unordered_map<std::string, std::string> _values;
88+
static std::string MakeKey(std::string_view section, std::string_view name);
8889
static int ValueHandler(void* user, const char* section, const char* name, const char* value);
8990
};
9091

0 commit comments

Comments
 (0)