1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-29 22:45:36 +00:00

Merge branch 'string_view' into 'master'

Pass std::string_view instead of const std::string&

See merge request OpenMW/openmw!1209
This commit is contained in:
psi29a 2021-09-09 20:41:16 +00:00
commit ac3fda0b3d
20 changed files with 170 additions and 42 deletions

View file

@ -145,8 +145,7 @@ namespace CSMWorld
return {};
}
const std::string& partName = it->second.first;
return partName;
return it->second.first;
}
bool ActorAdapter::ActorData::hasDependency(const std::string& id) const

View file

@ -9,6 +9,7 @@
#include <string>
#include <functional>
#include <memory>
#include <string_view>
#include <QVariant>
@ -153,7 +154,7 @@ namespace CSMWorld
///< Change the state of a record from base to modified, if it is not already.
/// \return True if the record was changed.
int searchId (const std::string& id) const override;
int searchId(std::string_view id) const override;
////< Search record with \a id.
/// \return index of record (if found) or -1 (not found)
@ -476,7 +477,7 @@ namespace CSMWorld
}
template<typename ESXRecordT, typename IdAccessorT>
int Collection<ESXRecordT, IdAccessorT>::searchId (const std::string& id) const
int Collection<ESXRecordT, IdAccessorT>::searchId(std::string_view id) const
{
std::string id2 = Misc::StringUtils::lowerCase(id);

View file

@ -4,6 +4,7 @@
#include <string>
#include <vector>
#include <memory>
#include <string_view>
#include "universalid.hpp"
#include "columns.hpp"
@ -61,7 +62,7 @@ namespace CSMWorld
UniversalId::Type type = UniversalId::Type_None) = 0;
///< \param type Will be ignored, unless the collection supports multiple record types
virtual int searchId (const std::string& id) const = 0;
virtual int searchId(std::string_view id) const = 0;
////< Search record with \a id.
/// \return index of record (if found) or -1 (not found)

View file

@ -391,7 +391,7 @@ int CSMWorld::Columns::getId (const std::string& name)
std::string name2 = Misc::StringUtils::lowerCase (name);
for (int i=0; sNames[i].mName; ++i)
if (Misc::StringUtils::ciEqual(sNames[i].mName, name2))
if (Misc::StringUtils::ciEqual(std::string_view(sNames[i].mName), name2))
return sNames[i].mId;
return -1;

View file

@ -97,7 +97,7 @@ void CSMWorld::InfoCollection::load (const Info& record, bool base)
}
}
int CSMWorld::InfoCollection::getInfoIndex (const std::string& id, const std::string& topic) const
int CSMWorld::InfoCollection::getInfoIndex(std::string_view id, std::string_view topic) const
{
// find the topic first
std::unordered_map<std::string, std::vector<std::pair<std::string, int> > >::const_iterator iter
@ -345,12 +345,12 @@ void CSMWorld::InfoCollection::appendBlankRecord (const std::string& id, Univer
insertRecord(std::move(record2), getInsertIndex(id, type, nullptr), type); // call InfoCollection::insertRecord()
}
int CSMWorld::InfoCollection::searchId (const std::string& id) const
int CSMWorld::InfoCollection::searchId(std::string_view id) const
{
std::string::size_type separator = id.find_last_of('#');
if (separator == std::string::npos)
throw std::runtime_error("invalid info ID: " + id);
throw std::runtime_error("invalid info ID: " + std::string(id));
return getInfoIndex(id.substr(separator+1), id.substr(0, separator));
}

View file

@ -2,6 +2,7 @@
#define CSM_WOLRD_INFOCOLLECTION_H
#include <unordered_map>
#include <string_view>
#include "collection.hpp"
#include "info.hpp"
@ -43,7 +44,7 @@ namespace CSMWorld
void load (const Info& record, bool base);
int getInfoIndex (const std::string& id, const std::string& topic) const;
int getInfoIndex(std::string_view id, std::string_view topic) const;
///< Return index for record \a id or -1 (if not present; deleted records are considered)
///
/// \param id info ID without topic prefix
@ -79,7 +80,7 @@ namespace CSMWorld
void appendBlankRecord (const std::string& id,
UniversalId::Type type = UniversalId::Type_None) override;
int searchId (const std::string& id) const override;
int searchId(std::string_view id) const override;
void appendRecord (std::unique_ptr<RecordBase> record,
UniversalId::Type type = UniversalId::Type_None) override;

View file

@ -7,6 +7,8 @@
#include "universalid.hpp"
#include "record.hpp"
#include <string_view>
namespace CSMWorld
{
template<>
@ -261,7 +263,7 @@ void CSMWorld::RefCollection::cloneRecord (const std::string& origin,
insertRecord(std::move(copy), getAppendIndex(destination, type)); // call RefCollection::insertRecord()
}
int CSMWorld::RefCollection::searchId (const std::string& id) const
int CSMWorld::RefCollection::searchId(std::string_view id) const
{
return searchId(extractIdNum(id));
}

View file

@ -2,6 +2,7 @@
#define CSM_WOLRD_REFCOLLECTION_H
#include <map>
#include <string_view>
#include "../doc/stage.hpp"
@ -56,7 +57,7 @@ namespace CSMWorld
const std::string& destination,
const UniversalId::Type type);
virtual int searchId (const std::string& id) const;
virtual int searchId(std::string_view id) const;
virtual void appendRecord (std::unique_ptr<RecordBase> record,
UniversalId::Type type = UniversalId::Type_None);

View file

@ -2,6 +2,7 @@
#include <stdexcept>
#include <memory>
#include <string_view>
#include <components/esm/esmreader.hpp>
@ -787,7 +788,7 @@ void CSMWorld::RefIdCollection::appendBlankRecord (const std::string& id, Univer
mData.appendRecord (type, id, false);
}
int CSMWorld::RefIdCollection::searchId (const std::string& id) const
int CSMWorld::RefIdCollection::searchId(std::string_view id) const
{
RefIdData::LocalIndex localIndex = mData.searchId (id);

View file

@ -4,6 +4,7 @@
#include <vector>
#include <map>
#include <deque>
#include <string_view>
#include "columnbase.hpp"
#include "collectionbase.hpp"
@ -85,7 +86,7 @@ namespace CSMWorld
void appendBlankRecord (const std::string& id, UniversalId::Type type) override;
///< \param type Will be ignored, unless the collection supports multiple record types
int searchId (const std::string& id) const override;
int searchId(std::string_view id) const override;
////< Search record with \a id.
/// \return index of record (if found) or -1 (not found)

View file

@ -2,6 +2,7 @@
#include <cassert>
#include <memory>
#include <string_view>
CSMWorld::RefIdDataContainerBase::~RefIdDataContainerBase() {}
@ -74,8 +75,7 @@ int CSMWorld::RefIdData::localToGlobalIndex (const LocalIndex& index)
return globalIndex;
}
CSMWorld::RefIdData::LocalIndex CSMWorld::RefIdData::searchId (
const std::string& id) const
CSMWorld::RefIdData::LocalIndex CSMWorld::RefIdData::searchId(std::string_view id) const
{
std::string id2 = Misc::StringUtils::lowerCase (id);

View file

@ -5,6 +5,7 @@
#include <map>
#include <memory>
#include <cassert>
#include <string_view>
#include <components/esm/loadacti.hpp>
#include <components/esm/loadalch.hpp>
@ -277,7 +278,7 @@ namespace CSMWorld
int localToGlobalIndex (const LocalIndex& index) const;
LocalIndex searchId (const std::string& id) const;
LocalIndex searchId(std::string_view id) const;
void erase (int index, int count);

View file

@ -3,6 +3,7 @@
#include <sstream>
#include <stdexcept>
#include <algorithm>
#include <string_view>
#include <components/vfs/manager.hpp>
@ -83,7 +84,7 @@ int CSMWorld::Resources::getIndex (const std::string& id) const
return index;
}
int CSMWorld::Resources::searchId (const std::string& id) const
int CSMWorld::Resources::searchId(std::string_view id) const
{
std::string id2 = Misc::StringUtils::lowerCase (id);

View file

@ -4,6 +4,7 @@
#include <string>
#include <map>
#include <vector>
#include <string_view>
#include "universalid.hpp"
@ -35,7 +36,7 @@ namespace CSMWorld
int getIndex (const std::string& id) const;
int searchId (const std::string& id) const;
int searchId(std::string_view id) const;
UniversalId::Type getType() const;
};

View file

@ -96,7 +96,7 @@ namespace CSVRender
for (int i = 0; i < ESM::PRT_Count; ++i)
{
auto type = (ESM::PartReferenceType) i;
const std::string partId(mActorData->getPart(type));
const std::string_view partId = mActorData->getPart(type);
attachBodyPart(type, getBodyPartMesh(partId));
}
}
@ -115,7 +115,7 @@ namespace CSVRender
}
}
std::string Actor::getBodyPartMesh(const std::string& bodyPartId)
std::string Actor::getBodyPartMesh(std::string_view bodyPartId)
{
const auto& bodyParts = mData.getBodyParts();

View file

@ -2,6 +2,7 @@
#define OPENCS_VIEW_RENDER_ACTOR_H
#include <string>
#include <string_view>
#include <osg/ref_ptr>
@ -54,7 +55,7 @@ namespace CSVRender
void loadBodyParts();
void attachBodyPart(ESM::PartReferenceType, const std::string& mesh);
std::string getBodyPartMesh(const std::string& bodyPartId);
std::string getBodyPartMesh(std::string_view bodyPartId);
static const std::string MeshPrefix;

View file

@ -376,7 +376,9 @@ namespace MWGui
{
for (const std::string& keyword : keywords)
{
if(Misc::StringUtils::ciEqual(MyGUI::LanguageManager::getInstance().replaceTags("#{" + keyword + "}"), button->getCaption()))
if (Misc::StringUtils::ciEqual(
MyGUI::LanguageManager::getInstance().replaceTags("#{" + keyword + "}").asUTF8(),
button->getCaption().asUTF8()))
{
return button;
}

View file

@ -1,6 +1,10 @@
#include <gtest/gtest.h>
#include "components/misc/stringops.hpp"
#include <string>
#include <string_view>
#include <type_traits>
struct PartialBinarySearchTest : public ::testing::Test
{
protected:
@ -12,10 +16,6 @@ struct PartialBinarySearchTest : public ::testing::Test
std::sort(mDataVec.begin(), mDataVec.end(), Misc::StringUtils::ciLess);
}
void TearDown() override
{
}
bool matches(const std::string& keyword)
{
return Misc::StringUtils::partialBinarySearch(mDataVec.begin(), mDataVec.end(), keyword) != mDataVec.end();
@ -51,3 +51,97 @@ TEST_F (PartialBinarySearchTest, ci_test)
std::string unicode1 = "\u04151 \u0418"; // CYRILLIC CAPITAL LETTER IE, CYRILLIC CAPITAL LETTER I
EXPECT_TRUE( Misc::StringUtils::lowerCase(unicode1) == unicode1 );
}
namespace
{
using ::Misc::StringUtils;
using namespace ::testing;
template <class T>
struct MiscStringUtilsCiEqualEmptyTest : Test {};
TYPED_TEST_SUITE_P(MiscStringUtilsCiEqualEmptyTest);
TYPED_TEST_P(MiscStringUtilsCiEqualEmptyTest, empty_strings_should_be_equal)
{
EXPECT_TRUE(StringUtils::ciEqual(typename TypeParam::first_type {}, typename TypeParam::second_type {}));
}
REGISTER_TYPED_TEST_SUITE_P(MiscStringUtilsCiEqualEmptyTest,
empty_strings_should_be_equal
);
using EmptyStringTypePairsTypes = Types<
std::pair<std::string, std::string>,
std::pair<std::string, std::string_view>,
std::pair<std::string, const char[1]>,
std::pair<std::string_view, std::string>,
std::pair<std::string_view, std::string_view>,
std::pair<std::string_view, const char[1]>,
std::pair<const char[1], std::string>,
std::pair<const char[1], std::string_view>,
std::pair<const char[1], const char[1]>
>;
INSTANTIATE_TYPED_TEST_SUITE_P(EmptyStringTypePairs, MiscStringUtilsCiEqualEmptyTest, EmptyStringTypePairsTypes);
template <class T>
struct MiscStringUtilsCiEqualNotEmptyTest : Test {};
TYPED_TEST_SUITE_P(MiscStringUtilsCiEqualNotEmptyTest);
using RawValue = const char[4];
constexpr RawValue foo = "foo";
constexpr RawValue fooUpper = "FOO";
constexpr RawValue bar = "bar";
template <typename T>
using Value = std::conditional_t<std::is_same_v<T, RawValue>, RawValue&, T>;
TYPED_TEST_P(MiscStringUtilsCiEqualNotEmptyTest, same_strings_should_be_equal)
{
const Value<typename TypeParam::first_type> a {foo};
const Value<typename TypeParam::second_type> b {foo};
EXPECT_TRUE(StringUtils::ciEqual(a, b)) << a << "\n" << b;
}
TYPED_TEST_P(MiscStringUtilsCiEqualNotEmptyTest, same_strings_with_different_case_sensetivity_should_be_equal)
{
const Value<typename TypeParam::first_type> a {foo};
const Value<typename TypeParam::second_type> b {fooUpper};
EXPECT_TRUE(StringUtils::ciEqual(a, b)) << a << "\n" << b;
}
TYPED_TEST_P(MiscStringUtilsCiEqualNotEmptyTest, different_strings_content_should_not_be_equal)
{
const Value<typename TypeParam::first_type> a {foo};
const Value<typename TypeParam::second_type> b {bar};
EXPECT_FALSE(StringUtils::ciEqual(a, b)) << a << "\n" << b;
}
REGISTER_TYPED_TEST_SUITE_P(MiscStringUtilsCiEqualNotEmptyTest,
same_strings_should_be_equal,
same_strings_with_different_case_sensetivity_should_be_equal,
different_strings_content_should_not_be_equal
);
using NotEmptyStringTypePairsTypes = Types<
std::pair<std::string, std::string>,
std::pair<std::string, std::string_view>,
std::pair<std::string, const char[4]>,
std::pair<std::string_view, std::string>,
std::pair<std::string_view, std::string_view>,
std::pair<std::string_view, const char[4]>,
std::pair<const char[4], std::string>,
std::pair<const char[4], std::string_view>,
std::pair<const char[4], const char[4]>
>;
INSTANTIATE_TYPED_TEST_SUITE_P(NotEmptyStringTypePairs, MiscStringUtilsCiEqualNotEmptyTest, NotEmptyStringTypePairsTypes);
TEST(MiscStringUtilsCiEqualTest, string_with_different_length_should_not_be_equal)
{
EXPECT_FALSE(StringUtils::ciEqual(std::string("a"), std::string("aa")));
}
}

View file

@ -4,6 +4,8 @@
#include <cctype>
#include <string>
#include <algorithm>
#include <string_view>
#include <iterator>
#include "utf8stream.hpp"
@ -109,18 +111,34 @@ public:
return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end(), ci());
}
static bool ciEqual(const std::string &x, const std::string &y) {
if (x.size() != y.size()) {
template <class X, class Y>
static bool ciEqual(const X& x, const Y& y)
{
if (std::size(x) != std::size(y))
return false;
}
std::string::const_iterator xit = x.begin();
std::string::const_iterator yit = y.begin();
for (; xit != x.end(); ++xit, ++yit) {
if (toLower(*xit) != toLower(*yit)) {
return false;
}
}
return true;
return std::equal(std::begin(x), std::end(x), std::begin(y),
[] (char l, char r) { return toLower(l) == toLower(r); });
}
template <std::size_t n>
static auto ciEqual(const char(& x)[n], const char(& y)[n])
{
static_assert(n > 0);
return ciEqual(std::string_view(x, n - 1), std::string_view(y, n - 1));
}
template <std::size_t n, class T>
static auto ciEqual(const char(& x)[n], const T& y)
{
static_assert(n > 0);
return ciEqual(std::string_view(x, n - 1), y);
}
template <std::size_t n, class T>
static auto ciEqual(const T& x, const char(& y)[n])
{
static_assert(n > 0);
return ciEqual(x, std::string_view(y, n - 1));
}
static int ciCompareLen(const std::string &x, const std::string &y, size_t len)
@ -157,9 +175,9 @@ public:
}
/// Returns lower case copy of input string
static std::string lowerCase(const std::string &in)
static std::string lowerCase(std::string_view in)
{
std::string out = in;
std::string out(in);
lowerCaseInPlace(out);
return out;
}

View file

@ -9,6 +9,9 @@
#include <components/misc/stringops.hpp>
#include <cstring>
#include <string_view>
namespace SceneUtil
{
@ -24,7 +27,7 @@ namespace SceneUtil
void FindByClassVisitor::apply(osg::Node &node)
{
if (Misc::StringUtils::ciEqual(node.className(), mNameToFind))
if (Misc::StringUtils::ciEqual(std::string_view(node.className()), mNameToFind))
mFoundNodes.push_back(&node);
traverse(node);