diff options
-rw-r--r-- | dist/patch.stl_vector.h.diff | 30 | ||||
-rw-r--r-- | document/src/vespa/document/base/idstring.cpp | 96 | ||||
-rw-r--r-- | document/src/vespa/document/base/idstring.h | 38 | ||||
-rw-r--r-- | fnet/src/tests/frt/method_pt/method_pt.cpp | 18 | ||||
-rw-r--r-- | searchlib/src/tests/queryeval/queryeval.cpp | 33 | ||||
-rw-r--r-- | searchlib/src/vespa/searchlib/diskindex/diskindex.cpp | 12 | ||||
-rw-r--r-- | searchlib/src/vespa/searchlib/diskindex/diskindex.h | 20 | ||||
-rw-r--r-- | searchlib/src/vespa/searchlib/index/field_length_info.h | 8 | ||||
-rw-r--r-- | searchlib/src/vespa/searchlib/index/postinglistcounts.h | 15 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/stllike/string.cpp | 25 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/stllike/string.h | 238 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/stllike/string.hpp | 28 |
12 files changed, 263 insertions, 298 deletions
diff --git a/dist/patch.stl_vector.h.diff b/dist/patch.stl_vector.h.diff new file mode 100644 index 00000000000..e2474c3a32b --- /dev/null +++ b/dist/patch.stl_vector.h.diff @@ -0,0 +1,30 @@ +--- /opt/rh/gcc-toolset-12/root/usr/include/c++/12/bits/stl_vector.h 2022-09-14 17:00:12.000000000 +0000 ++++ ./stl_vector.h 2023-02-10 13:24:44.885703192 +0000 +@@ -1814,10 +1814,10 @@ + #if __cplusplus < 201103L + // Called by insert(p,x) + void +- _M_insert_aux(iterator __position, const value_type& __x); ++ _M_insert_aux(iterator __position, const value_type& __x) __attribute((noinline)); + + void +- _M_realloc_insert(iterator __position, const value_type& __x); ++ _M_realloc_insert(iterator __position, const value_type& __x) __attribute((noinline)); + #else + // A value_type object constructed with _Alloc_traits::construct() + // and destroyed with _Alloc_traits::destroy(). +@@ -1860,12 +1860,12 @@ + template<typename _Arg> + _GLIBCXX20_CONSTEXPR + void +- _M_insert_aux(iterator __position, _Arg&& __arg); ++ _M_insert_aux(iterator __position, _Arg&& __arg) __attribute((noinline)); + + template<typename... _Args> + _GLIBCXX20_CONSTEXPR + void +- _M_realloc_insert(iterator __position, _Args&&... __args); ++ _M_realloc_insert(iterator __position, _Args&&... __args) __attribute((noinline)); + + // Either move-construct at the end, or forward to _M_insert_aux. + _GLIBCXX20_CONSTEXPR diff --git a/document/src/vespa/document/base/idstring.cpp b/document/src/vespa/document/base/idstring.cpp index f3e41981c8e..d684d135d87 100644 --- a/document/src/vespa/document/base/idstring.cpp +++ b/document/src/vespa/document/base/idstring.cpp @@ -5,9 +5,8 @@ #include <vespa/document/bucket/bucketid.h> #include <vespa/vespalib/util/md5.h> #include <vespa/vespalib/util/stringfmt.h> -#include <vespa/vespalib/util/optimized.h> -#include <cerrno> #include <cstring> +#include <charconv> using vespalib::string; using vespalib::stringref; @@ -54,83 +53,31 @@ union FourByte { uint32_t as32; }; -const FourByte _G_null = {{'n', 'u', 'l', 'l'}}; -const TwoByte _G_id = {{'i', 'd'}}; +constexpr FourByte G_null = {{'n', 'u', 'l', 'l'}}; +constexpr TwoByte G_id = {{'i', 'd'}}; -#ifdef __x86_64__ -typedef char v16qi __attribute__ ((__vector_size__(16))); - -v16qi _G_zero = { ':', ':', ':', ':', ':', ':', ':', ':', ':', ':', ':', ':', ':', ':', ':', ':' }; -#endif - -inline const char * -fmemchr(const char * s, const char * e) -{ -#ifdef __x86_64__ - while (s+15 < e) { -#ifdef __clang__ - v16qi tmpCurrent = __builtin_ia32_lddqu(s); - v16qi tmp0 = tmpCurrent == _G_zero; -#else - v16qi tmpCurrent = __builtin_ia32_loaddqu(s); - v16qi tmp0 = __builtin_ia32_pcmpeqb128(tmpCurrent, _G_zero); -#endif - uint32_t charMap = __builtin_ia32_pmovmskb128(tmp0); // 1 in charMap equals to '\0' in input buffer - if (__builtin_expect(charMap, 1)) { - return s + vespalib::Optimized::lsbIdx(charMap); - } - s+=16; - } - - const char c(':'); - while (s+3 < e) { - if (s[0] == c) { - return s; - } - if (s[1] == c) { - return s+1; - } - if (s[2] == c) { - return s+2; - } - if (s[3] == c) { - return s+3; - } - s+=4; - } - while (s < e) { - if (s[0] == c) { - return s; - } - s++; - } - return nullptr; -#else +const char * +fmemchr(const char * s, const char * e) noexcept { return static_cast<const char *>(memchr(s, ':', e - s)); -#endif } -namespace { - // Avoid issues with primitive alignment when reading from buffer. // Requires caller to ensure buffer is big enough to read from. template <typename T> -inline T read_unaligned(const char* buf) noexcept +constexpr T read_unaligned(const char* buf) noexcept { T tmp; memcpy(&tmp, buf, sizeof(T)); return tmp; } -} - void verifyIdString(const char * id, size_t sz_) { - if (sz_ > 4) { - if ((_G_id.as16 == read_unaligned<uint16_t>(id)) && (id[2] == ':')) { + if (sz_ > 4) [[likely]] { + if ((G_id.as16 == read_unaligned<uint16_t>(id)) && (id[2] == ':')) [[likely]] { return; - } else if ((sz_ == 6) && (_G_null.as32 == read_unaligned<uint32_t>(id)) && (id[4] == ':') && (id[5] == ':')) { + } else if ((sz_ == 6) && (G_null.as32 == read_unaligned<uint32_t>(id)) && (id[4] == ':') && (id[5] == ':')) { reportNoId(id); } else if (sz_ > 8) { reportNoSchemeSeparator(id); @@ -159,29 +106,30 @@ validate(uint16_t numComponents) constexpr uint32_t NAMESPACE_OFFSET = 3; -const vespalib::stringref DEFAULT_ID("id::::"); +constexpr vespalib::stringref DEFAULT_ID("id::::", 6); union LocationUnion { uint8_t _key[16]; IdString::LocationType _location[2]; }; -uint64_t parseNumber(stringref number) { - char* errPos = nullptr; - errno = 0; - uint64_t n = strtoul(number.data(), &errPos, 10); - if (*errPos) { - throw IdParseException("'n'-value must be a 64-bit number. It was " + number, VESPA_STRLOC); +uint64_t +parseNumber(stringref s) { + uint64_t n(0); + auto res = std::from_chars(s.data(), s.data() + s.size(), n, 10); + if (res.ptr != s.data() + s.size()) [[unlikely]]{ + throw IdParseException("'n'-value must be a 64-bit number. It was " + s, VESPA_STRLOC); } - if (errno == ERANGE) { - throw IdParseException("'n'-value out of range (" + number + ")", VESPA_STRLOC); + if (res.ec == std::errc::result_out_of_range) [[unlikely]] { + throw IdParseException("'n'-value out of range (" + s + ")", VESPA_STRLOC); } return n; } -void setLocation(IdString::LocationType &loc, IdString::LocationType val, +void +setLocation(IdString::LocationType &loc, IdString::LocationType val, bool &has_set_location, stringref key_values) { - if (has_set_location) { + if (has_set_location) [[unlikely]] { throw IdParseException("Illegal key combination in " + key_values); } loc = val; @@ -193,7 +141,7 @@ void setLocation(IdString::LocationType &loc, IdString::LocationType val, const IdString::Offsets IdString::Offsets::DefaultID(DEFAULT_ID); -IdString::Offsets::Offsets(stringref id) +IdString::Offsets::Offsets(stringref id) noexcept : _offsets() { compute(id); diff --git a/document/src/vespa/document/base/idstring.h b/document/src/vespa/document/base/idstring.h index bb752bd456e..176d810fccc 100644 --- a/document/src/vespa/document/base/idstring.h +++ b/document/src/vespa/document/base/idstring.h @@ -25,40 +25,40 @@ public: explicit IdString(vespalib::stringref ns); IdString(); - vespalib::stringref getNamespace() const { return getComponent(0); } - bool hasDocType() const { return size(1) != 0; } - vespalib::stringref getDocType() const { return getComponent(1); } - LocationType getLocation() const { return _location; } - bool hasNumber() const { return _has_number; } - uint64_t getNumber() const { return _location; } - bool hasGroup() const { return _groupOffset != 0; } - vespalib::stringref getGroup() const { - return vespalib::stringref(getRawId().c_str() + _groupOffset, offset(3) - _groupOffset - 1); + [[nodiscard]] vespalib::stringref getNamespace() const { return getComponent(0); } + [[nodiscard]] bool hasDocType() const { return size(1) != 0; } + [[nodiscard]] vespalib::stringref getDocType() const { return getComponent(1); } + [[nodiscard]] LocationType getLocation() const { return _location; } + [[nodiscard]] bool hasNumber() const { return _has_number; } + [[nodiscard]] uint64_t getNumber() const { return _location; } + [[nodiscard]] bool hasGroup() const { return _groupOffset != 0; } + [[nodiscard]] vespalib::stringref getGroup() const { + return {getRawId().c_str() + _groupOffset, size_t(offset(3) - _groupOffset - 1)}; } - vespalib::stringref getNamespaceSpecific() const { - return vespalib::stringref(_rawId.c_str() + offset(3), _rawId.size() - offset(3)); + [[nodiscard]] vespalib::stringref getNamespaceSpecific() const { + return {_rawId.c_str() + offset(3), _rawId.size() - offset(3)}; } bool operator==(const IdString& other) const { return toString() == other.toString(); } - const vespalib::string & toString() const { return _rawId; } + [[nodiscard]] const vespalib::string & toString() const { return _rawId; } private: - uint16_t offset(uint32_t index) const { return _offsets[index]; } - uint16_t size(uint32_t index) const { return std::max(0, int(offset(index+1)) - int(offset(index)) - 1); } - vespalib::stringref getComponent(size_t index) const { return vespalib::stringref(_rawId.c_str() + offset(index), size(index)); } - const vespalib::string & getRawId() const { return _rawId; } + [[nodiscard]] uint16_t offset(uint32_t index) const { return _offsets[index]; } + [[nodiscard]] uint16_t size(uint32_t index) const { return std::max(0, int(offset(index+1)) - int(offset(index)) - 1); } + [[nodiscard]] vespalib::stringref getComponent(size_t index) const { return {_rawId.c_str() + offset(index), size(index)}; } + [[nodiscard]] const vespalib::string & getRawId() const { return _rawId; } class Offsets { public: - Offsets() = default; - uint16_t compute(vespalib::stringref id); + Offsets() noexcept = default; + VESPA_DLL_LOCAL uint16_t compute(vespalib::stringref id); uint16_t operator [] (size_t i) const { return _offsets[i]; } static const Offsets DefaultID; private: static constexpr uint32_t MAX_COMPONENTS = 4; - Offsets(vespalib::stringref id); + VESPA_DLL_LOCAL explicit Offsets(vespalib::stringref id) noexcept; uint16_t _offsets[MAX_COMPONENTS]; }; diff --git a/fnet/src/tests/frt/method_pt/method_pt.cpp b/fnet/src/tests/frt/method_pt/method_pt.cpp index bc42a31d91b..2ac706369ae 100644 --- a/fnet/src/tests/frt/method_pt/method_pt.cpp +++ b/fnet/src/tests/frt/method_pt/method_pt.cpp @@ -32,7 +32,7 @@ public: /** * Destructor. No cleanup needed for base class. */ - virtual ~MediumA(void) { } + virtual ~MediumA() = default; virtual void foo() = 0; }; @@ -45,18 +45,14 @@ public: /** * Destructor. No cleanup needed for base class. */ - virtual ~MediumB(void) { } + virtual ~MediumB() = default; virtual void bar() = 0; }; //------------------------------------------------------------- -#ifdef __clang__ #define UNUSED_MEMBER [[maybe_unused]] -#else -#define UNUSED_MEMBER -#endif class ComplexA { @@ -70,7 +66,7 @@ public: /** * Destructor. No cleanup needed for base class. */ - virtual ~ComplexA(void) { } + virtual ~ComplexA() = default; ComplexA() : _fill1(1), _fill2(2), _fill3(3) {} virtual void foo() {} @@ -89,7 +85,7 @@ public: /** * Destructor. No cleanup needed for base class. */ - virtual ~ComplexB(void) { } + virtual ~ComplexB() = default; ComplexB() : _fill1(1), _fill2(2), _fill3(3) {} virtual void bar() {} @@ -184,7 +180,7 @@ void finiTest() { TEST("method pt") { - FRT_RPCRequest *req = _supervisor->AllocRPCRequest(); + FRT_RPCRequest *req = FRT_Supervisor::AllocRPCRequest(); req->SetMethodName("simpleMethod"); _target->InvokeSync(req, 60.0); EXPECT_TRUE(!req->IsError()); @@ -192,7 +188,7 @@ TEST("method pt") { //-------------------------------- MEDIUM req->SubRef(); - req = _supervisor->AllocRPCRequest(); + req = FRT_Supervisor::AllocRPCRequest(); req->SetMethodName("mediumMethod"); _target->InvokeSync(req, 60.0); EXPECT_TRUE(!req->IsError()); @@ -200,7 +196,7 @@ TEST("method pt") { //-------------------------------- COMPLEX req->SubRef(); - req = _supervisor->AllocRPCRequest(); + req = FRT_Supervisor::AllocRPCRequest(); req->SetMethodName("complexMethod"); _target->InvokeSync(req, 60.0); EXPECT_TRUE(!req->IsError()); diff --git a/searchlib/src/tests/queryeval/queryeval.cpp b/searchlib/src/tests/queryeval/queryeval.cpp index 62815f285c4..517e633f328 100644 --- a/searchlib/src/tests/queryeval/queryeval.cpp +++ b/searchlib/src/tests/queryeval/queryeval.cpp @@ -85,7 +85,7 @@ std::unique_ptr<sourceselector::Iterator> selector() { //----------------------------------------------------------------------------- void testMultiSearch(SearchIterator & search) { - MultiSearch & ms = dynamic_cast<MultiSearch &>(search); + auto & ms = dynamic_cast<MultiSearch &>(search); ms.initRange(3, 309); EXPECT_EQUAL(2u, ms.getDocId()); EXPECT_EQUAL(309u, ms.getEndId()); @@ -123,12 +123,12 @@ TEST("test that strict AND.andWith steals filter and places it correctly based o ch.emplace_back(new TrueSearch(tfmd)); ch.emplace_back(new TrueSearch(tfmd)); SearchIterator::UP search(AndSearch::create({ch[0], ch[1]}, true)); - static_cast<AndSearch &>(*search).estimate(7); + dynamic_cast<AndSearch &>(*search).estimate(7); auto filter = std::make_unique<TrueSearch>(tfmd); SearchIterator * filterP = filter.get(); EXPECT_TRUE(nullptr == search->andWith(std::move(filter), 8).get()); - const MultiSearch::Children & andChildren = static_cast<MultiSearch &>(*search).getChildren(); + const auto & andChildren = dynamic_cast<MultiSearch &>(*search).getChildren(); EXPECT_EQUAL(3u, andChildren.size()); EXPECT_EQUAL(ch[0], andChildren[0].get()); EXPECT_EQUAL(filterP, andChildren[1].get()); @@ -147,8 +147,8 @@ TEST("test that strict AND.andWith steals filter and places it correctly based o class NonStrictTrueSearch : public TrueSearch { public: - NonStrictTrueSearch(TermFieldMatchData & tfmd) : TrueSearch(tfmd) { } - Trinary is_strict() const override { return Trinary::False; } + explicit NonStrictTrueSearch(TermFieldMatchData & tfmd) : TrueSearch(tfmd) { } + [[nodiscard]] Trinary is_strict() const override { return Trinary::False; } }; TEST("test that strict AND.andWith does not place non-strict iterator first") { @@ -157,11 +157,11 @@ TEST("test that strict AND.andWith does not place non-strict iterator first") { ch.emplace_back(new TrueSearch(tfmd)); ch.emplace_back(new TrueSearch(tfmd)); SearchIterator::UP search(AndSearch::create({ch[0], ch[1]}, true)); - static_cast<AndSearch &>(*search).estimate(7); + dynamic_cast<AndSearch &>(*search).estimate(7); auto filter = std::make_unique<NonStrictTrueSearch>(tfmd); SearchIterator * filterP = filter.get(); EXPECT_TRUE(nullptr == search->andWith(std::move(filter), 6).get()); - const MultiSearch::Children & andChildren = static_cast<MultiSearch &>(*search).getChildren(); + const auto & andChildren = dynamic_cast<MultiSearch &>(*search).getChildren(); EXPECT_EQUAL(3u, andChildren.size()); EXPECT_EQUAL(ch[0], andChildren[0].get()); EXPECT_EQUAL(filterP, andChildren[1].get()); @@ -288,7 +288,7 @@ TEST("testOr") { class TestInsertRemoveSearch : public MultiSearch { public: - TestInsertRemoveSearch(ChildrenIterators children) : + explicit TestInsertRemoveSearch(ChildrenIterators children) : MultiSearch(std::move(children)), _accumRemove(0), _accumInsert(0) @@ -338,7 +338,7 @@ TEST("testMultiSearch") { class DummySingleValueBitNumericAttributeBlueprint : public SimpleLeafBlueprint { public: - DummySingleValueBitNumericAttributeBlueprint(const SimpleResult & result) : + explicit DummySingleValueBitNumericAttributeBlueprint(const SimpleResult & result) : SimpleLeafBlueprint(FieldSpecBaseList()), _a("a", search::GrowStrategy(), false), _sc(), @@ -601,14 +601,7 @@ getExpectedSlime() { } TEST("testDump") { -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wshadow" -#endif - using Source = SourceBlenderSearch::Child; -#ifdef __clang__ -#pragma clang diagnostic pop -#endif + using SBChild = SourceBlenderSearch::Child; SearchIterator::UP search = AndSearch::create( { AndNotSearch::create(search2("+", "-"), true), @@ -618,9 +611,9 @@ TEST("testDump") { new ONearSearch(search2("onear_a", "onear_b"), TermFieldMatchDataArray(), 10, true), OrSearch::create(search2("or_a", "or_b"), false), RankSearch::create(search2("rank_a", "rank_b"),false), - SourceBlenderSearch::create(selector(), Collect<Source, SourceBlenderSearch::Children>() - .add(Source(simple("blend_a"), 2)) - .add(Source(simple("blend_b"), 4)), + SourceBlenderSearch::create(selector(), Collect<SBChild, SourceBlenderSearch::Children>() + .add(SBChild(simple("blend_a"), 2)) + .add(SBChild(simple("blend_b"), 4)), true) }, true); vespalib::string sas = search->asString(); EXPECT_TRUE(sas.size() > 50); diff --git a/searchlib/src/vespa/searchlib/diskindex/diskindex.cpp b/searchlib/src/vespa/searchlib/diskindex/diskindex.cpp index 99107749610..90bcaabc7a5 100644 --- a/searchlib/src/vespa/searchlib/diskindex/diskindex.cpp +++ b/searchlib/src/vespa/searchlib/diskindex/diskindex.cpp @@ -35,8 +35,8 @@ DiskIndex::LookupResult::LookupResult() noexcept { } -DiskIndex::Key::Key() = default; -DiskIndex::Key::Key(IndexList indexes, vespalib::stringref word) : +DiskIndex::Key::Key() noexcept = default; +DiskIndex::Key::Key(IndexList indexes, vespalib::stringref word) noexcept : _word(word), _indexes(std::move(indexes)) { @@ -302,7 +302,7 @@ DiskIndex::readPostingList(const LookupResult &lookupRes) const SchemaUtil::IndexIterator it(_schema, lookupRes.indexId); handle->_file = _postingFiles[it.getIndex()].get(); if (handle->_file == nullptr) { - return PostingListHandle::UP(); + return {}; } const uint32_t firstSegment = 0; const uint32_t numSegments = 0; // means all segments @@ -316,7 +316,7 @@ DiskIndex::readBitVector(const LookupResult &lookupRes) const SchemaUtil::IndexIterator it(_schema, lookupRes.indexId); BitVectorDictionary * dict = _bitVectorDicts[it.getIndex()].get(); if (dict == nullptr) { - return BitVector::UP(); + return {}; } return dict->lookup(lookupRes.wordNum); } @@ -330,7 +330,7 @@ DiskIndex::calculateSize() namespace { -DiskIndex::LookupResult _G_nothing; +DiskIndex::LookupResult G_nothing; class LookupCache { public: @@ -352,7 +352,7 @@ public: return result; } } - return _G_nothing; + return G_nothing; } private: diff --git a/searchlib/src/vespa/searchlib/diskindex/diskindex.h b/searchlib/src/vespa/searchlib/diskindex/diskindex.h index faa562e5809..9672939a741 100644 --- a/searchlib/src/vespa/searchlib/diskindex/diskindex.h +++ b/searchlib/src/vespa/searchlib/diskindex/diskindex.h @@ -32,8 +32,8 @@ public: uint64_t bitOffset; using UP = std::unique_ptr<LookupResult>; LookupResult() noexcept; - bool valid() const { return counts._numDocs > 0; } - void swap(LookupResult & rhs) { + bool valid() const noexcept { return counts._numDocs > 0; } + void swap(LookupResult & rhs) noexcept { std::swap(indexId , rhs.indexId); std::swap(wordNum , rhs.wordNum); counts.swap(rhs.counts); @@ -45,22 +45,22 @@ public: class Key { public: - Key(); - Key(IndexList indexes, vespalib::stringref word); + Key() noexcept; + Key(IndexList indexes, vespalib::stringref word) noexcept; Key(const Key &); Key & operator = (const Key &); - Key(Key &&) = default; - Key & operator = (Key &&) = default; + Key(Key &&) noexcept = default; + Key & operator = (Key &&) noexcept = default; ~Key(); - uint32_t hash() const { + uint32_t hash() const noexcept { return vespalib::hashValue(_word.c_str(), _word.size()); } - bool operator == (const Key & rhs) const { + bool operator == (const Key & rhs) const noexcept { return _word == rhs._word; } void push_back(uint32_t indexId) { _indexes.push_back(indexId); } - const IndexList & getIndexes() const { return _indexes; } - const vespalib::string & getWord() const { return _word; } + const IndexList & getIndexes() const noexcept { return _indexes; } + const vespalib::string & getWord() const noexcept { return _word; } private: vespalib::string _word; IndexList _indexes; diff --git a/searchlib/src/vespa/searchlib/index/field_length_info.h b/searchlib/src/vespa/searchlib/index/field_length_info.h index d1fba4bc6d2..03125e99a87 100644 --- a/searchlib/src/vespa/searchlib/index/field_length_info.h +++ b/searchlib/src/vespa/searchlib/index/field_length_info.h @@ -15,19 +15,19 @@ private: uint32_t _num_samples; public: - FieldLengthInfo() + FieldLengthInfo() noexcept : FieldLengthInfo(0.0, 0) { } - FieldLengthInfo(double average_field_length, uint32_t num_samples) + FieldLengthInfo(double average_field_length, uint32_t num_samples) noexcept : _average_field_length(average_field_length), _num_samples(num_samples) { } - double get_average_field_length() const { return _average_field_length; } - uint32_t get_num_samples() const { return _num_samples; } + [[nodiscard]] double get_average_field_length() const noexcept { return _average_field_length; } + [[nodiscard]] uint32_t get_num_samples() const noexcept { return _num_samples; } }; } diff --git a/searchlib/src/vespa/searchlib/index/postinglistcounts.h b/searchlib/src/vespa/searchlib/index/postinglistcounts.h index 3d76e8203cb..1e58b2f5ef7 100644 --- a/searchlib/src/vespa/searchlib/index/postinglistcounts.h +++ b/searchlib/src/vespa/searchlib/index/postinglistcounts.h @@ -29,15 +29,14 @@ public: uint32_t _numDocs; // Number of documents in segment uint32_t _lastDoc; // Last document id in segment - Segment() + Segment() noexcept : _bitLength(0), _numDocs(0), _lastDoc(0) { } bool - operator==(const Segment &rhs) const - { + operator==(const Segment &rhs) const noexcept { return (_bitLength == rhs._bitLength && _numDocs == rhs._numDocs && _lastDoc == rhs._lastDoc); @@ -59,24 +58,24 @@ public: */ std::vector<Segment> _segments; - PostingListCounts() + PostingListCounts() noexcept : _numDocs(0), _bitLength(0), _segments() { } - void swap(PostingListCounts & rhs) { + void swap(PostingListCounts & rhs) noexcept { std::swap(_numDocs, rhs._numDocs); std::swap(_bitLength, rhs._bitLength); std::swap(_segments, rhs._segments); } - void clear() { + void clear() noexcept { _bitLength = 0; _numDocs = 0; _segments.clear(); } - bool operator==(const PostingListCounts &rhs) const { + bool operator==(const PostingListCounts &rhs) const noexcept { return (_numDocs == rhs._numDocs && _bitLength == rhs._bitLength && _segments == rhs._segments); @@ -92,7 +91,7 @@ public: uint64_t _accNumDocs; // Used by prefix search for now. PostingListCounts _counts; - PostingListOffsetAndCounts() + PostingListOffsetAndCounts() noexcept : _offset(0), _accNumDocs(0u), _counts() diff --git a/vespalib/src/vespa/vespalib/stllike/string.cpp b/vespalib/src/vespa/vespalib/stllike/string.cpp index 460bb0d39c6..5b78d7ad56b 100644 --- a/vespalib/src/vespa/vespalib/stllike/string.cpp +++ b/vespalib/src/vespa/vespalib/stllike/string.cpp @@ -2,14 +2,11 @@ #include <vespa/vespalib/stllike/string.hpp> #include <ostream> -#include <istream> namespace vespalib { -const stringref::size_type stringref::npos; - stringref::size_type -stringref::rfind(const char * s, size_type e) const { +stringref::rfind(const char * s, size_type e) const noexcept { size_type n = strlen(s); if (n <= size()) { size_type sz = std::min(size()-n, e); @@ -30,7 +27,7 @@ stringref::rfind(const char * s, size_type e) const { } stringref::size_type -stringref::find(stringref s, size_type start) const { +stringref::find(stringref s, size_type start) const noexcept { const char *buf = begin()+start; const char *e = end() - s.size(); while (buf <= e) { @@ -69,7 +66,7 @@ template std::ostream & operator << (std::ostream & os, const string & v); template std::istream & operator >> (std::istream & is, string & v); string -operator + (stringref a, const char * b) +operator + (stringref a, const char * b) noexcept { string t(a); t += b; @@ -77,7 +74,7 @@ operator + (stringref a, const char * b) } string -operator + (const char * a, stringref b) +operator + (const char * a, stringref b) noexcept { string t(a); t += b; @@ -85,7 +82,7 @@ operator + (const char * a, stringref b) } string -operator + (stringref a, stringref b) +operator + (stringref a, stringref b) noexcept { string t(a); t += b; @@ -94,13 +91,13 @@ operator + (stringref a, stringref b) template class small_string<48>; -template string operator + (const string & a, const string & b); -template string operator + (const string & a, stringref b); -template string operator + (stringref a, const string & b); -template string operator + (const string & a, const char * b); -template string operator + (const char * a, const string & b); +template string operator + (const string & a, const string & b) noexcept; +template string operator + (const string & a, stringref b) noexcept; +template string operator + (stringref a, const string & b) noexcept; +template string operator + (const string & a, const char * b) noexcept; +template string operator + (const char * a, const string & b) noexcept; -const string &empty_string() { +const string &empty_string() noexcept { static string empty; return empty; } diff --git a/vespalib/src/vespa/vespalib/stllike/string.h b/vespalib/src/vespa/vespalib/stllike/string.h index 8bcb03ef781..6c40c33853b 100644 --- a/vespalib/src/vespa/vespalib/stllike/string.h +++ b/vespalib/src/vespa/vespalib/stllike/string.h @@ -22,37 +22,36 @@ class stringref public: using const_iterator = const char *; using size_type = size_t; - static const size_type npos = static_cast<size_type>(-1); - stringref() : _s(""), _sz(0) { } + static constexpr size_type npos = static_cast<size_type>(-1); + constexpr stringref() noexcept : _s(""), _sz(0) { } stringref(const char * s) noexcept : _s(s), _sz(strlen(s)) { } - stringref(const char * s, size_type sz) noexcept : _s(s), _sz(sz) { } - stringref(const std::string & s) noexcept : _s(s.c_str()), _sz(s.size()) { } + constexpr stringref(const char * s, size_type sz) noexcept : _s(s), _sz(sz) { } + constexpr stringref(const std::string & s) noexcept : _s(s.c_str()), _sz(s.size()) { } stringref(const stringref &) noexcept = default; stringref & operator =(const stringref &) noexcept = default; stringref(stringref &&) noexcept = default; stringref & operator =(stringref &&) noexcept = default; /** - * return a pointer to the data held, or NULL. + * return a pointer to the data held, or nullptr. * Note that the data may not be zero terminated, and a default - * constructed stringref will give a NULL pointer back. If you + * constructed stringref will give a nullptr pointer back. If you * need to make sure data() gives a valid zero-terminated string * you should make a string from the stringref. **/ - const char * data() const { return _s; } - - size_type size() const { return _sz; } - size_type length() const { return size(); } - bool empty() const { return _sz == 0; } - const char * begin() const { return data(); } - const char * end() const { return begin() + size(); } - const char * rbegin() const { return end() - 1; } - const char * rend() const { return begin() - 1; } - stringref substr(size_type start, size_type sz=npos) const { + [[nodiscard]] const char * data() const noexcept { return _s; } + [[nodiscard]] size_type size() const noexcept { return _sz; } + [[nodiscard]] size_type length() const noexcept { return size(); } + [[nodiscard]] bool empty() const noexcept { return _sz == 0; } + [[nodiscard]] const char * begin() const noexcept { return data(); } + [[nodiscard]] const char * end() const noexcept { return begin() + size(); } + [[nodiscard]] const char * rbegin() const noexcept { return end() - 1; } + [[nodiscard]] const char * rend() const noexcept { return begin() - 1; } + [[nodiscard]] stringref substr(size_type start, size_type sz=npos) const noexcept { if (start < size()) { - return stringref(data() + start, std::min(sz, size()-start)); + return {data() + start, std::min(sz, size()-start)}; } - return stringref(); + return {}; } /** @@ -63,10 +62,10 @@ public: * @return index from the start of the string at which the character * was found, or npos if the character could not be located */ - size_type find(const char * s, size_type start=0) const { + size_type find(const char * s, size_type start=0) const noexcept { const char *buf = begin()+start; const char *found = (const char *)strstr(buf, s); - return (found != NULL) ? (found - begin()) : (size_type)npos; + return (found != nullptr) ? (found - begin()) : (size_type)npos; } /** * Find the first occurrence of a string, searching from @c start @@ -76,7 +75,7 @@ public: * @return index from the start of the string at which the character * was found, or npos if the character could not be located */ - size_type find(stringref s, size_type start=0) const; + [[nodiscard]] size_type find(stringref s, size_type start=0) const noexcept; /** * Find the first occurrence of a character, searching from @c start * @@ -85,10 +84,10 @@ public: * @return index from the start of the string at which the character * was found, or npos if the character could not be located */ - size_type find(char c, size_type start=0) const { + [[nodiscard]] size_type find(char c, size_type start=0) const noexcept { const char *buf = begin()+start; const char *found = (const char *)memchr(buf, c, _sz-start); - return (found != NULL) ? (found - begin()) : (size_type)npos; + return (found != nullptr) ? (found - begin()) : (size_type)npos; } /** * Find the last occurrence of a substring, starting at e and @@ -99,7 +98,7 @@ public: * @return index from the start of the string at which the substring * was found, or npos if the substring could not be located */ - size_type rfind(char c, size_type e=npos) const { + [[nodiscard]] size_type rfind(char c, size_type e=npos) const noexcept { if (!empty()) { const char *b = begin(); for (size_type i(std::min(size()-1, e) + 1); i > 0;) { @@ -121,8 +120,8 @@ public: * @return index from the start of the string at which the substring * was found, or npos if the substring could not be located */ - size_type rfind(const char * s, size_type e=npos) const; - int compare(stringref s) const noexcept { return compare(s.data(), s.size()); } + size_type rfind(const char * s, size_type e=npos) const noexcept; + [[nodiscard]] int compare(stringref s) const noexcept { return compare(s.data(), s.size()); } int compare(const char *s, size_type sz) const noexcept { int diff(memcmp(_s, s, std::min(sz, size()))); return (diff != 0) ? diff : (size() - sz); @@ -138,8 +137,8 @@ public: return (memcmp(data(), prefix.data(), prefix.size()) == 0); } - const char & operator [] (size_t i) const { return _s[i]; } - operator std::string () const { return std::string(_s, _sz); } + const char & operator [] (size_t i) const noexcept { return _s[i]; } + operator std::string () const { return {_s, _sz}; } bool operator < (const char * s) const noexcept { return compare(s, strlen(s)) < 0; } bool operator < (const std::string & s) const noexcept { return compare(s.data(), s.size()) < 0; } bool operator < (stringref s) const noexcept { return compare(s.data(), s.size()) < 0; } @@ -161,8 +160,8 @@ public: private: const char *_s; size_type _sz; - friend bool operator == (const std::string & a, stringref b) { return b == a; } - friend bool operator != (const std::string & a, stringref b) { return b != a; } + friend bool operator == (const std::string & a, stringref b) noexcept { return b == a; } + friend bool operator != (const std::string & a, stringref b) noexcept { return b != a; } friend std::ostream & operator << (std::ostream & os, stringref v); }; @@ -188,8 +187,8 @@ public: using const_iterator = const char *; using reverse_iterator = char *; using const_reverse_iterator = const char *; - static const size_type npos = static_cast<size_type>(-1); - small_string() noexcept : _buf(_stack), _sz(0), _bufferSize(StackSize) { _stack[0] = '\0'; } + static constexpr size_type npos = static_cast<size_type>(-1); + constexpr small_string() noexcept : _buf(_stack), _sz(0), _bufferSize(StackSize) { _stack[0] = '\0'; } small_string(const char * s) noexcept : _buf(_stack), _sz(s ? strlen(s) : 0) { init(s); } small_string(const void * s, size_type sz) noexcept : _buf(_stack), _sz(sz) { init(s); } small_string(stringref s) noexcept : _buf(_stack), _sz(s.size()) { init(s.data()); } @@ -205,7 +204,7 @@ public: { init(rhs.data()+pos); } - small_string(size_type sz, char c) + small_string(size_type sz, char c) noexcept : _buf(_stack), _sz(0), _bufferSize(StackSize) { reserve(sz); @@ -215,7 +214,7 @@ public: } template<typename Iterator> - small_string(Iterator s, Iterator e); + small_string(Iterator s, Iterator e) noexcept; ~small_string() { if (__builtin_expect(isAllocated(), false)) { @@ -246,14 +245,14 @@ public: std::swap(*this, rhs); } operator std::string () const { return std::string(c_str(), size()); } - operator stringref () const { return stringref(c_str(), size()); } - char at(size_t i) const { return buffer()[i]; } - char & at(size_t i) { return buffer()[i]; } - const char & operator [] (size_t i) const { return buffer()[i]; } - char & operator [] (size_t i) { return buffer()[i]; } + operator stringref () const noexcept { return stringref(c_str(), size()); } + [[nodiscard]] char at(size_t i) const noexcept { return buffer()[i]; } + char & at(size_t i) noexcept { return buffer()[i]; } + const char & operator [] (size_t i) const noexcept { return buffer()[i]; } + char & operator [] (size_t i) noexcept { return buffer()[i]; } /** if there is a newline at the end of the string, remove it and return true */ - bool chomp() { + bool chomp() noexcept { if (size() > 0 && *rbegin() == '\n') { _resize(size() - 1); return true; @@ -264,7 +263,7 @@ public: /** * Remove the last character of the string */ - void pop_back() { + void pop_back() noexcept { _resize(size() - 1); } @@ -287,7 +286,7 @@ public: * @return index from the start of the string at which the substring * was found, or npos if the substring could not be located */ - size_type rfind(const char * s, size_type e=npos) const; + size_type rfind(const char * s, size_type e=npos) const noexcept; /** * Find the last occurrence of a character, starting at e and @@ -298,7 +297,7 @@ public: * @return index from the start of the string at which the character * was found, or npos if the character could not be located */ - size_type rfind(char c, size_type e=npos) const { + [[nodiscard]] size_type rfind(char c, size_type e=npos) const noexcept { size_type sz = std::min(size()-1, e)+1; const char *b = buffer(); while (sz-- > 0) { @@ -308,10 +307,14 @@ public: } return npos; } - size_type find_last_of(char c, size_type e=npos) const { return rfind(c, e); } - size_type find_first_of(char c, size_type start=0) const { return find(c, start); } + [[nodiscard]] size_type find_last_of(char c, size_type e=npos) const noexcept { + return rfind(c, e); + } + [[nodiscard]] size_type find_first_of(char c, size_type start=0) const noexcept { + return find(c, start); + } - size_type find_first_not_of(char c, size_type start=0) const { + [[nodiscard]] size_type find_first_not_of(char c, size_type start=0) const noexcept { size_t p(start); const char *buf = buffer(); for(size_t m(size()); (p < m) && (buf[p] == c); p++); @@ -326,7 +329,9 @@ public: * @return index from the start of the string at which the substring * was found, or npos if the substring could not be located */ - size_type find(const small_string & s, size_type start=0) const { return find(s.c_str(), start); } + [[nodiscard]] size_type find(const small_string & s, size_type start=0) const noexcept { + return find(s.c_str(), start); + } /** * Find the first occurrence of a substring, searching from @c start @@ -336,10 +341,10 @@ public: * @return index from the start of the string at which the substring * was found, or npos if the substring could not be located */ - size_type find(const char * s, size_type start=0) const { + size_type find(const char * s, size_type start=0) const noexcept { const char *buf = buffer()+start; const char *found = strstr(buf, s); - return (found != NULL) ? (found - buffer()) : (size_type)npos; + return (found != nullptr) ? (found - buffer()) : (size_type)npos; } /** @@ -350,10 +355,10 @@ public: * @return index from the start of the string at which the character * was found, or npos if the character could not be located */ - size_type find(char c, size_type start=0) const { + [[nodiscard]] size_type find(char c, size_type start=0) const noexcept { const char *buf = buffer()+start; const char *found = (const char *)memchr(buf, c, _sz-start); - return (found != NULL) ? (found - buffer()) : (size_type)npos; + return (found != nullptr) ? (found - buffer()) : (size_type)npos; } small_string & assign(const char * s) noexcept { return assign(s, strlen(s)); } small_string & assign(const void * s, size_type sz) noexcept; @@ -364,18 +369,18 @@ public: if (data() != rhs.data()) assign(rhs.data(), rhs.size()); return *this; } - small_string & push_back(char c) { return append(&c, 1); } - small_string & append(char c) { return append(&c, 1); } - small_string & append(const char * s) { return append(s, strlen(s)); } - small_string & append(stringref s) { return append(s.data(), s.size()); } - small_string & append(const std::string & s) { return append(s.data(), s.size()); } - small_string & append(const small_string & s) { return append(s.data(), s.size()); } - small_string & append(const void * s, size_type sz); - small_string & operator += (char c) { return append(c); } - small_string & operator += (const char * s) { return append(s); } - small_string & operator += (stringref s) { return append(s); } - small_string & operator += (const std::string & s) { return append(s); } - small_string & operator += (const small_string & s) { return append(s); } + small_string & push_back(char c) noexcept { return append(&c, 1); } + small_string & append(char c) noexcept { return append(&c, 1); } + small_string & append(const char * s) noexcept { return append(s, strlen(s)); } + small_string & append(stringref s) noexcept { return append(s.data(), s.size()); } + small_string & append(const std::string & s) noexcept { return append(s.data(), s.size()); } + small_string & append(const small_string & s) noexcept { return append(s.data(), s.size()); } + small_string & append(const void * s, size_type sz) noexcept; + small_string & operator += (char c) noexcept { return append(c); } + small_string & operator += (const char * s) noexcept { return append(s); } + small_string & operator += (stringref s) noexcept { return append(s); } + small_string & operator += (const std::string & s) noexcept { return append(s); } + small_string & operator += (const small_string & s) noexcept { return append(s); } /** * Return a new string comprised of the contents of a sub-range of this @@ -386,7 +391,7 @@ public: * end of the string, only the remaining part will be returned. * @return a substring of *this */ - small_string substr(size_type start, size_type sz=npos) const { + [[nodiscard]] small_string substr(size_type start, size_type sz=npos) const noexcept { if (start < size()) { const char *s = c_str(); return small_string(s + start, std::min(sz, size()-start)); @@ -394,15 +399,15 @@ public: return small_string(); } - small_string & insert(iterator p, const_iterator f, const_iterator l) { return insert(p-c_str(), f, l-f); } - small_string & insert(size_type start, stringref v) { return insert(start, v.data(), v.size()); } - small_string & insert(size_type start, const void * v, size_type sz); + small_string & insert(iterator p, const_iterator f, const_iterator l) noexcept { return insert(p-c_str(), f, l-f); } + small_string & insert(size_type start, stringref v) noexcept { return insert(start, v.data(), v.size()); } + small_string & insert(size_type start, const void * v, size_type sz) noexcept; /** * Erases the content of the string, leaving it zero-length. * Does not alter string capacity. */ - void clear() { + void clear() noexcept { _sz = 0; buffer()[0] = 0; } @@ -412,7 +417,7 @@ public: * leaving it zero-length. Capacity is reset to the original small * string stack size */ - void reset() { + void reset() noexcept { if (isAllocated()) { free(buffer()); _bufferSize = StackSize; @@ -420,19 +425,19 @@ public: } clear(); } - const_iterator begin() const { return buffer(); } - const_iterator end() const { return buffer() + size(); } - iterator begin() { return buffer(); } - iterator end() { return buffer() + size(); } - const_reverse_iterator rbegin() const { return end() - 1; } - const_reverse_iterator rend() const { return begin() - 1; } - reverse_iterator rbegin() { return end() - 1; } - reverse_iterator rend() { return begin() - 1; } - const char * c_str() const { return buffer(); } - const char * data() const { return buffer(); } - size_type size() const { return _sz; } - size_type length() const { return size(); } - bool empty() const { return _sz == 0; } + [[nodiscard]] const_iterator begin() const noexcept { return buffer(); } + [[nodiscard]] const_iterator end() const noexcept { return buffer() + size(); } + iterator begin() noexcept { return buffer(); } + iterator end() noexcept { return buffer() + size(); } + [[nodiscard]] const_reverse_iterator rbegin() const noexcept { return end() - 1; } + [[nodiscard]] const_reverse_iterator rend() const noexcept { return begin() - 1; } + reverse_iterator rbegin() noexcept { return end() - 1; } + reverse_iterator rend() noexcept { return begin() - 1; } + [[nodiscard]] const char * c_str() const noexcept { return buffer(); } + [[nodiscard]] const char * data() const noexcept { return buffer(); } + [[nodiscard]] size_type size() const noexcept { return _sz; } + [[nodiscard]] size_type length() const noexcept { return size(); } + [[nodiscard]] bool empty() const noexcept { return _sz == 0; } /** * at position p1, replace n1 characters with the contents of s @@ -441,7 +446,7 @@ public: * @param n1 how many old characters should be replaced, cannot go outside old string * @param s new replacement content **/ - small_string& replace (size_t p1, size_t n1, const small_string& s ) { + small_string& replace (size_t p1, size_t n1, const small_string& s ) noexcept { return replace(p1, n1, s.c_str(), s.size()); } @@ -455,7 +460,7 @@ public: * @param p2 position in s where replacement content starts * @param n2 how many new characters to use **/ - small_string& replace (size_t p1, size_t n1, const small_string& s, size_t p2, size_t n2); + small_string& replace (size_t p1, size_t n1, const small_string& s, size_t p2, size_t n2) noexcept; /** * at position p1, replace n1 characters with @@ -466,7 +471,7 @@ public: * @param s pointer to new content * @param n2 how many new characters to use **/ - small_string& replace (size_t p1, size_t n1, const char *s, size_t n2); + small_string& replace (size_t p1, size_t n1, const char *s, size_t n2) noexcept; /** * at position p1, replace n1 characters with the contents of s @@ -475,7 +480,7 @@ public: * @param n1 how many old characters should be replaced, cannot go outside old string * @param s pointer to new replacement content **/ - small_string& replace (size_t p1, size_t n1, const char* s ) { + small_string& replace (size_t p1, size_t n1, const char* s ) noexcept { return replace(p1, n1, s, strlen(s)); } @@ -510,13 +515,13 @@ public: template<typename T> bool operator != (const T& s) const noexcept { return ! operator == (s); } - int compare(const small_string & s) const noexcept { return compare(s.c_str(), s.size()); } + [[nodiscard]] int compare(const small_string & s) const noexcept { return compare(s.c_str(), s.size()); } int compare(const char *s, size_t sz) const noexcept { int diff(memcmp(buffer(), s, std::min(sz, size()))); return (diff != 0) ? diff : (size() - sz); } - size_type capacity() const { return _bufferSize - 1; } + [[nodiscard]] size_type capacity() const noexcept { return _bufferSize - 1; } /** * Make string exactly newSz in length removing characters at @@ -526,7 +531,7 @@ public: * @param c default character to use when initializing uninitialized memory. */ - void resize(size_type newSz, char padding = '\0') { + void resize(size_type newSz, char padding = '\0') noexcept { if (newSz > capacity()) { reserve(newSz); } @@ -543,7 +548,7 @@ public: * * @param newSz new size of string. */ - void append_from_reserved(size_type sz); + void append_from_reserved(size_type sz) noexcept; /** * Ensure string has at least newCapacity characters of available @@ -552,21 +557,21 @@ public: * * @param newCapacity new minimum capacity of string */ - void reserve(size_type newCapacity) { + void reserve(size_type newCapacity) noexcept { reserveBytes(newCapacity + 1); } - size_t count_allocated_memory() const { + [[nodiscard]] size_t count_allocated_memory() const noexcept { return sizeof(small_string) + (isAllocated() ? _bufferSize : 0); } - size_t count_used_memory() const { + [[nodiscard]] size_t count_used_memory() const noexcept { return sizeof(small_string) - StackSize + size(); } private: - void assign_slower(const void * s, size_type sz) __attribute((noinline)); + void assign_slower(const void * s, size_type sz) noexcept __attribute((noinline)); void init_slower(const void *s) noexcept __attribute((noinline)); - void _reserveBytes(size_type newBufferSize); - void reserveBytes(size_type newBufferSize) { + void _reserveBytes(size_type newBufferSize) noexcept; + void reserveBytes(size_type newBufferSize) noexcept { if (newBufferSize > _bufferSize) { _reserveBytes(newBufferSize); } @@ -586,11 +591,11 @@ private: } } using isize_type = uint32_t; - bool needAlloc(isize_type add) const { return (add + _sz + 1) > _bufferSize; } - bool isAllocated() const { return _buf != _stack; } - char * buffer() { return _buf; } - const char * buffer() const { return _buf; } - VESPA_DLL_LOCAL void appendAlloc(const void * s, size_type sz) __attribute__((noinline)); + [[nodiscard]] bool needAlloc(isize_type add) const noexcept { return (add + _sz + 1) > _bufferSize; } + [[nodiscard]] bool isAllocated() const noexcept { return _buf != _stack; } + char * buffer() noexcept { return _buf; } + [[nodiscard]] const char * buffer() const noexcept { return _buf; } + VESPA_DLL_LOCAL void appendAlloc(const void * s, size_type sz) noexcept __attribute__((noinline)); void init(const void *s) noexcept { if (__builtin_expect(_sz < StackSize, true)) { _bufferSize = StackSize; @@ -602,7 +607,7 @@ private: init_slower(s); } } - void _resize(size_type newSz) { + void _resize(size_type newSz) noexcept { _sz = newSz; *end() = '\0'; } @@ -618,7 +623,7 @@ private: template <uint32_t StackSize> template<typename Iterator> -small_string<StackSize>::small_string(Iterator s, Iterator e) : +small_string<StackSize>::small_string(Iterator s, Iterator e) noexcept : _buf(_stack), _sz(0), _bufferSize(StackSize) @@ -629,30 +634,27 @@ small_string<StackSize>::small_string(Iterator s, Iterator e) : } } -template <uint32_t StackSize> -const size_t small_string<StackSize>::npos; - using string = small_string<48>; template<uint32_t StackSize> small_string<StackSize> -operator + (const small_string<StackSize> & a, const small_string<StackSize> & b); +operator + (const small_string<StackSize> & a, const small_string<StackSize> & b) noexcept; template<uint32_t StackSize> small_string<StackSize> -operator + (const small_string<StackSize> & a, stringref b); +operator + (const small_string<StackSize> & a, stringref b) noexcept; template<uint32_t StackSize> small_string<StackSize> -operator + (stringref a, const small_string<StackSize> & b); +operator + (stringref a, const small_string<StackSize> & b) noexcept; template<uint32_t StackSize> small_string<StackSize> -operator + (const small_string<StackSize> & a, const char * b); +operator + (const small_string<StackSize> & a, const char * b) noexcept; template<uint32_t StackSize> small_string<StackSize> -operator + (const char * a, const small_string<StackSize> & b); +operator + (const char * a, const small_string<StackSize> & b) noexcept; #if __cplusplus < 201709L || (!defined(__clang__) && __GNUC__ == 13) template<typename T, uint32_t StackSize> @@ -677,22 +679,22 @@ operator < (const T& a, const small_string<StackSize>& b) noexcept return b > a; } -string operator + (stringref a, stringref b); -string operator + (const char * a, stringref b); -string operator + (stringref a, const char * b); +string operator + (stringref a, stringref b) noexcept; +string operator + (const char * a, stringref b) noexcept; +string operator + (stringref a, const char * b) noexcept; -inline bool contains(stringref text, stringref key) { +inline bool contains(stringref text, stringref key) noexcept { return text.find(key) != stringref::npos; } -inline bool starts_with(stringref text, stringref key) { +inline bool starts_with(stringref text, stringref key) noexcept { if (text.size() >= key.size()) { return memcmp(text.begin(), key.begin(), key.size()) == 0; } return false; } -inline bool ends_with(stringref text, stringref key) { +inline bool ends_with(stringref text, stringref key) noexcept { if (text.size() >= key.size()) { return memcmp(text.end()-key.size(), key.begin(), key.size()) == 0; } @@ -700,7 +702,7 @@ inline bool ends_with(stringref text, stringref key) { } // returns a reference to a shared empty string -const string &empty_string(); +const string &empty_string() noexcept; /** * Utility function to format an unsigned integer into a new diff --git a/vespalib/src/vespa/vespalib/stllike/string.hpp b/vespalib/src/vespa/vespalib/stllike/string.hpp index 7a438353e85..e0144ab6f85 100644 --- a/vespalib/src/vespa/vespalib/stllike/string.hpp +++ b/vespalib/src/vespa/vespalib/stllike/string.hpp @@ -7,14 +7,14 @@ namespace vespalib { template <uint32_t StackSize> void -small_string<StackSize>::append_from_reserved(size_type sz) { +small_string<StackSize>::append_from_reserved(size_type sz) noexcept { assert(size() + sz <= capacity()); _resize(size() + sz); } template <uint32_t StackSize> void -small_string<StackSize>::_reserveBytes(size_type newBufferSize) { +small_string<StackSize>::_reserveBytes(size_type newBufferSize) noexcept { if (isAllocated()) { _buf = (char *) realloc(_buf, newBufferSize); } else { @@ -28,14 +28,14 @@ small_string<StackSize>::_reserveBytes(size_type newBufferSize) { template <uint32_t StackSize> small_string<StackSize>& -small_string<StackSize>::replace (size_t p1, size_t n1, const small_string& s, size_t p2, size_t n2 ) { +small_string<StackSize>::replace (size_t p1, size_t n1, const small_string& s, size_t p2, size_t n2 ) noexcept { assert(s.size() >= (p2+n2)); return replace(p1, n1, s.c_str()+p2, n2); } template <uint32_t StackSize> small_string<StackSize>& -small_string<StackSize>::replace (size_t p1, size_t n1, const char *s, size_t n2 ) { +small_string<StackSize>::replace (size_t p1, size_t n1, const char *s, size_t n2 ) noexcept { assert (size() >= (p1 + n1)); const size_t newSz = n2 + size() - n1; if (n1 < n2) { @@ -50,7 +50,7 @@ small_string<StackSize>::replace (size_t p1, size_t n1, const char *s, size_t n2 template <uint32_t StackSize> typename small_string<StackSize>::size_type -small_string<StackSize>::rfind(const char * s, size_type e) const { +small_string<StackSize>::rfind(const char * s, size_type e) const noexcept { size_type n = strlen(s); if (n <= size()) { size_type sz = std::min(size()-n, e); @@ -85,7 +85,7 @@ small_string<StackSize>::assign(const void * s, size_type sz) noexcept { } template <uint32_t StackSize> -void small_string<StackSize>::assign_slower(const void * s, size_type sz) +void small_string<StackSize>::assign_slower(const void * s, size_type sz) noexcept { reset(); append(s, sz); @@ -101,7 +101,7 @@ void small_string<StackSize>::init_slower(const void *s) noexcept } template <uint32_t StackSize> -void small_string<StackSize>::appendAlloc(const void * s, size_type addSz) +void small_string<StackSize>::appendAlloc(const void * s, size_type addSz) noexcept { size_type newBufferSize = roundUp2inN(_sz+addSz+1); char * buf = (char *) malloc(newBufferSize); @@ -118,7 +118,7 @@ void small_string<StackSize>::appendAlloc(const void * s, size_type addSz) template <uint32_t StackSize> small_string<StackSize> & -small_string<StackSize>::insert(size_type start, const void * v, size_type sz) +small_string<StackSize>::insert(size_type start, const void * v, size_type sz) noexcept { if (start < size()) { if ((static_cast<const char *>(v)+sz < c_str()) || (c_str()+size() < v)) { @@ -143,7 +143,7 @@ small_string<StackSize>::insert(size_type start, const void * v, size_type sz) template <uint32_t StackSize> small_string<StackSize> & -small_string<StackSize>::append(const void * s, size_type addSz) +small_string<StackSize>::append(const void * s, size_type addSz) noexcept { if (needAlloc(addSz)) { appendAlloc(s, addSz); @@ -158,7 +158,7 @@ small_string<StackSize>::append(const void * s, size_type addSz) template<uint32_t StackSize> small_string<StackSize> -operator + (const small_string<StackSize> & a, const small_string<StackSize> & b) +operator + (const small_string<StackSize> & a, const small_string<StackSize> & b) noexcept { small_string<StackSize> t(a); t += b; @@ -167,7 +167,7 @@ operator + (const small_string<StackSize> & a, const small_string<StackSize> & b template<uint32_t StackSize> small_string<StackSize> -operator + (const small_string<StackSize> & a, stringref b) +operator + (const small_string<StackSize> & a, stringref b) noexcept { small_string<StackSize> t(a); t += b; @@ -176,7 +176,7 @@ operator + (const small_string<StackSize> & a, stringref b) template<uint32_t StackSize> small_string<StackSize> -operator + (stringref a, const small_string<StackSize> & b) +operator + (stringref a, const small_string<StackSize> & b) noexcept { small_string<StackSize> t(a); t += b; @@ -185,7 +185,7 @@ operator + (stringref a, const small_string<StackSize> & b) template<uint32_t StackSize> small_string<StackSize> -operator + (const small_string<StackSize> & a, const char * b) +operator + (const small_string<StackSize> & a, const char * b) noexcept { small_string<StackSize> t(a); t += b; @@ -194,7 +194,7 @@ operator + (const small_string<StackSize> & a, const char * b) template<uint32_t StackSize> small_string<StackSize> -operator + (const char * a, const small_string<StackSize> & b) +operator + (const char * a, const small_string<StackSize> & b) noexcept { small_string<StackSize> t(a); t += b; |