diff --git a/doomsday/libs/core/include/de/core/app.h b/doomsday/libs/core/include/de/core/app.h index f6f475bfea..5a9a282d8a 100644 --- a/doomsday/libs/core/include/de/core/app.h +++ b/doomsday/libs/core/include/de/core/app.h @@ -322,7 +322,7 @@ class DE_PUBLIC App : DE_OBSERVES(Clock, TimeChange) * * @return Number of files found. */ - static int findInPackages(const CString &partialPath, FileIndex::FoundFiles &files); + static int findInPackages(const String &partialPath, FileIndex::FoundFiles &files); /** * Checks if an asset exists. @@ -331,7 +331,7 @@ class DE_PUBLIC App : DE_OBSERVES(Clock, TimeChange) * * @return @c true, if assetInfo() can be called. */ - static bool assetExists(const CString &identifier); + static bool assetExists(const String &identifier); /** * Retrieves the namespace of an asset. @@ -340,7 +340,7 @@ class DE_PUBLIC App : DE_OBSERVES(Clock, TimeChange) * * @return Asset namespace accessor. */ - static Package::Asset asset(const CString &identifier); + static Package::Asset asset(const String &identifier); /** * Returns the application's script system. @@ -361,7 +361,7 @@ class DE_PUBLIC App : DE_OBSERVES(Clock, TimeChange) * * @return Variable. */ - static Variable &config(const CString &name); + static Variable &config(const String &name); /** * Returns the web API URL. Always includes the protocol and ends with a slash. diff --git a/doomsday/libs/core/include/de/core/config.h b/doomsday/libs/core/include/de/core/config.h index 46d6e7d42e..f039a8ba21 100644 --- a/doomsday/libs/core/include/de/core/config.h +++ b/doomsday/libs/core/include/de/core/config.h @@ -78,19 +78,19 @@ class DE_PUBLIC Config : public RecordAccessor, public IObject * * @return Variable whose value was set. */ - Variable &set(const CString &name, bool value); + Variable &set(const String &name, bool value); /// @copydoc set() - Variable &set(const CString &name, Value::Text const &value); + Variable &set(const String &name, Value::Text const &value); /// @copydoc set() - Variable &set(const CString &name, Value::Number const &value); + Variable &set(const String &name, Value::Number const &value); /// @copydoc set() - Variable &set(const CString &name, dint value); + Variable &set(const String &name, dint value); /// @copydoc set() - Variable &set(const CString &name, duint value); + Variable &set(const String &name, duint value); /** * Sets the value of a variable, creating the variable if it doesn't exist. @@ -98,7 +98,7 @@ class DE_PUBLIC Config : public RecordAccessor, public IObject * @param name Name of the variable. May contain subrecords using the dot notation. * @param value Array to use as the value of the variable. Ownership taken. */ - Variable &set(const CString &name, ArrayValue *value); + Variable &set(const String &name, ArrayValue *value); /** * Returns the old version, when a new installed version has been detected. @@ -111,7 +111,7 @@ class DE_PUBLIC Config : public RecordAccessor, public IObject Record const &objectNamespace() const; static Config &get(); - static Variable &get(const CString &name); + static Variable &get(const String &name); static bool exists(); private: diff --git a/doomsday/libs/core/include/de/data/block.h b/doomsday/libs/core/include/de/data/block.h index ab918d840e..2a3d891826 100644 --- a/doomsday/libs/core/include/de/data/block.h +++ b/doomsday/libs/core/include/de/data/block.h @@ -57,6 +57,7 @@ class DE_PUBLIC Block Block(const Block &other); Block(Block &&moved); Block(const char *nullTerminatedCStr); + Block(const std::string &str); Block(const void *data, Size length); /** diff --git a/doomsday/libs/core/include/de/data/cstring.h b/doomsday/libs/core/include/de/data/cstring.h index c46785be4f..c58ee75c61 100644 --- a/doomsday/libs/core/include/de/data/cstring.h +++ b/doomsday/libs/core/include/de/data/cstring.h @@ -56,6 +56,8 @@ class DE_PUBLIC CString updateEnd(); return _range.size(); } + bool isEmpty() const { return size() == 0; } + bool empty() const { return size() == 0; } bool contains(char ch) const; dsize indexOf(char ch, size_t from = 0) const; dsize indexOf(const char *cStr, size_t from = 0) const; diff --git a/doomsday/libs/core/include/de/data/hash.h b/doomsday/libs/core/include/de/data/hash.h index f2d0de38bb..0521e896f9 100644 --- a/doomsday/libs/core/include/de/data/hash.h +++ b/doomsday/libs/core/include/de/data/hash.h @@ -35,10 +35,55 @@ class Hash : public std::unordered_map public: Hash(); - void insert(const Key &key, const Value &value) { Base::operator[](key) = value; } - bool contains(const Key &key) const { return Base::find(key) != Base::end(); } + void insert(const Key &key, const Value &value) { Base::operator[](key) = value; } + void remove(const Key &key) { Base::erase(key); } + bool contains(const Key &key) const { return Base::find(key) != Base::end(); } + Value & operator[](const Key &key) { return Base::operator[](key); } + const Value &operator[](const Key &key) const { return Base::find(key)->second; } }; +template +class MutableHashIterator +{ + using Container = Hash; + using Iterator = typename Container::iterator; + + Container _hash; + Iterator _cur; + Iterator _next; + +public: + MutableHashIterator(Container &c) : _hash(c) + { + _next = c.begin(); + } + + bool hasNext() const + { + return _next != _hash.end(); + } + + Iterator &next() + { + _cur = _next++; + return _cur; + } + + const typename Container::key_type &key() const + { + return _cur->first; + } + + const typename Container::value_type::second_type &value() const + { + return _cur->second; + } + + void remove() + { + _hash.erase(_cur); + } +}; } // namespace de #endif // LIBCORE_HASH_H diff --git a/doomsday/libs/core/include/de/data/map.h b/doomsday/libs/core/include/de/data/map.h index 0feeb86cc5..4021fed965 100644 --- a/doomsday/libs/core/include/de/data/map.h +++ b/doomsday/libs/core/include/de/data/map.h @@ -40,8 +40,57 @@ class Map : public std::map using const_reverse_iterator = typename Base::const_reverse_iterator; void insert(const Key &key, const Value &value) { Base::operator[](key) = value; } + void remove(const Key &key) { Base::erase(key); } bool contains(const Key &key) const { return Base::find(key) != Base::end(); } const_iterator constFind(const Key &key) const { return Base::find(key); } + + void deleteAll() + { + for (auto i : *this) { delete i->second; } + } +}; + +template +class MutableMapIterator +{ + using Container = Map; + using Iterator = typename Container::iterator; + + Container _map; + Iterator _cur; + Iterator _next; + +public: + MutableMapIterator(Container &c) : _map(c) + { + _next = c.begin(); + } + + bool hasNext() const + { + return _next != _map.end(); + } + + Iterator &next() + { + _cur = _next++; + return _cur; + } + + const typename Container::key_type &key() const + { + return _cur->first; + } + + const typename Container::value_type::second_type &value() const + { + return _cur->second; + } + + void remove() + { + _map.erase(_cur); + } }; } // namespace de diff --git a/doomsday/libs/core/include/de/data/record.h b/doomsday/libs/core/include/de/data/record.h index b8554b4e33..c4d0b83ca3 100644 --- a/doomsday/libs/core/include/de/data/record.h +++ b/doomsday/libs/core/include/de/data/record.h @@ -70,14 +70,10 @@ class DE_PUBLIC Record /// All variables and subrecords in the record must have a name. @ingroup errors DE_ERROR(UnnamedError); - /// Name of the special variable that specifies super records. - static String const VAR_SUPER; - - /// Name of the special variable that identifies the source file. - static String const VAR_FILE; - - static String const VAR_INIT; - static String const VAR_NATIVE_SELF; + static const char *VAR_SUPER; ///< Special variable that specifies super records. + static const char *VAR_FILE; ///< Special variable that identifies the source file. + static const char *VAR_INIT; + static const char *VAR_NATIVE_SELF; typedef Hash Members; // unordered typedef Hash Subrecords; // unordered @@ -188,18 +184,18 @@ class DE_PUBLIC Record /** * Determines if the record contains a variable or a subrecord named @a variableName. */ - bool has(const CString &name) const; + bool has(const String &name) const; /** * Determines if the record contains a variable named @a variableName. */ - bool hasMember(const CString &variableName) const; + bool hasMember(const String &variableName) const; /** * Determines if the record contains a subrecord named @a subrecordName. * Subrecords are owned by this record. */ - bool hasSubrecord(const CString &subrecordName) const; + bool hasSubrecord(const String &subrecordName) const; /** * Determines if the record contains a variable @a recordName that @@ -210,7 +206,7 @@ class DE_PUBLIC Record * * @return @c true if the variable points to a record. */ - bool hasRecord(const CString &recordName) const; + bool hasRecord(const String &recordName) const; /** * Adds a new variable to the record. @@ -238,9 +234,9 @@ class DE_PUBLIC Record * * @return Caller gets ownership of the removed variable. */ - Variable *remove(const CString &variableName); + Variable *remove(const String &variableName); - Variable *tryRemove(const CString &variableName); + Variable *tryRemove(const String &variableName); /** * Adds a new variable to the record with a NoneValue. If there is an existing @@ -250,7 +246,7 @@ class DE_PUBLIC Record * * @return The new variable. */ - Variable &add(const CString &variableName, Variable::Flags variableFlag = Variable::DefaultMode); + Variable &add(const String &variableName, Variable::Flags variableFlag = Variable::DefaultMode); /** * Adds a number variable to the record. The variable is set up to only accept @@ -261,7 +257,7 @@ class DE_PUBLIC Record * * @return The number variable. */ - Variable &addNumber(const CString &variableName, Value::Number number); + Variable &addNumber(const String &variableName, Value::Number number); /** * Adds a number variable to the record with a Boolean semantic hint. The variable is @@ -273,7 +269,7 @@ class DE_PUBLIC Record * * @return The number variable. */ - Variable &addBoolean(const CString &variableName, bool booleanValue); + Variable &addBoolean(const String &variableName, bool booleanValue); /** * Adds a text variable to the record. The variable is set up to only accept @@ -284,9 +280,9 @@ class DE_PUBLIC Record * * @return The text variable. */ - Variable &addText(const CString &variableName, Value::Text const &text); + Variable &addText(const String &variableName, Value::Text const &text); - Variable &addTime(const CString &variableName, Time const &time); + Variable &addTime(const String &variableName, Time const &time); /** * Adds an array variable to the record. The variable is set up to only accept @@ -298,7 +294,7 @@ class DE_PUBLIC Record * * @return The array variable. */ - Variable &addArray(const CString &variableName, ArrayValue *array = 0); + Variable &addArray(const String &variableName, ArrayValue *array = 0); /** * Adds a dictionary variable to the record. The variable is set up to only accept @@ -308,7 +304,7 @@ class DE_PUBLIC Record * * @return The dictionary variable. */ - Variable &addDictionary(const CString &variableName); + Variable &addDictionary(const String &variableName); /** * Adds a block variable to the record. The variable is set up to only accept @@ -318,7 +314,7 @@ class DE_PUBLIC Record * * @return The block variable. */ - Variable &addBlock(const CString &variableName); + Variable &addBlock(const String &variableName); /** * Adds a function variable to the record. The variable is set up to only @@ -331,7 +327,7 @@ class DE_PUBLIC Record * * @return The function variable. */ - Variable &addFunction(const CString &variableName, Function *func); + Variable &addFunction(const String &variableName, Function *func); /** * Adds a new subrecord to the record. Adds a variable named @a name and gives @@ -344,7 +340,7 @@ class DE_PUBLIC Record * * @return @a subrecord, for convenience. */ - Record &add(const CString &name, Record *subrecord); + Record &add(const String &name, Record *subrecord); enum SubrecordAdditionBehavior { ReplaceExisting, KeepExisting }; @@ -362,7 +358,7 @@ class DE_PUBLIC Record * * @return The new subrecord. */ - Record &addSubrecord(const CString &name, SubrecordAdditionBehavior behavior = ReplaceExisting); + Record &addSubrecord(const String &name, SubrecordAdditionBehavior behavior = ReplaceExisting); /** * Removes a subrecord from the record. @@ -371,7 +367,7 @@ class DE_PUBLIC Record * * @return Caller gets ownership of the removed record. */ - Record *removeSubrecord(const CString &name); + Record *removeSubrecord(const String &name); /** * Sets the value of a variable, creating the variable if needed. @@ -381,38 +377,38 @@ class DE_PUBLIC Record * * @return Variable whose value was set. */ - Variable &set(const CString &name, bool value); + Variable &set(const String &name, bool value); /// @copydoc set() - Variable &set(const CString &name, char const *value); + Variable &set(const String &name, char const *value); /// @copydoc set() - Variable &set(const CString &name, Value::Text const &value); - Variable &set(const CString &name, Value::Number const &value); + Variable &set(const String &name, Value::Text const &value); + Variable &set(const String &name, Value::Number const &value); /// @copydoc set() - Variable &set(const CString &name, Value::Number value); + Variable &set(const String &name, Value::Number value); /// @copydoc set() - Variable &set(const CString &name, const NumberValue &value); + Variable &set(const String &name, const NumberValue &value); /// @copydoc set() - Variable &set(const CString &name, dint32 value); + Variable &set(const String &name, duint32 value); /// @copydoc set() - Variable &set(const CString &name, duint32 value); + Variable &set(const String &name, dint64 value); /// @copydoc set() - Variable &set(const CString &name, dint64 value); + Variable &set(const String &name, duint64 value); /// @copydoc set() - Variable &set(const CString &name, duint64 value); + Variable &set(const String &name, unsigned long value); /// @copydoc set() - Variable &set(const CString &name, unsigned long value); + Variable &set(const String &name, Time const &value); /// @copydoc set() - Variable &set(const CString &name, Time const &value); + Variable &set(const String &name, Block const &value); /// @copydoc set() Variable &set(const CString &name, Block const &value); @@ -426,7 +422,8 @@ class DE_PUBLIC Record * @param name Name of the variable. May contain subrecords using the dot notation. * @param value Array to use as the value of the variable. Ownership taken. */ - Variable &set(const CString &name, ArrayValue *value); + Variable &set(const String &name, ArrayValue *value); + Variable &set(const String &name, Value *value); Variable &set(const CString &name, Value *value); @@ -440,13 +437,13 @@ class DE_PUBLIC Record * @param separator Separator to append before the word, if the variable is not * currently empty. */ - Variable &appendWord(const CString &name, String const &word, String const &separator = " "); + Variable &appendWord(const String &name, const String &word, const String &separator = " "); - Variable &appendUniqueWord(const CString &name, String const &word, String const &separator = " "); + Variable &appendUniqueWord(const String &name, const String &word, const String &separator = " "); - Variable &appendMultipleUniqueWords(const CString &name, String const &words, String const &separator = " "); + Variable &appendMultipleUniqueWords(const String &name, const String &words, const String &separator = " "); - Variable &appendToArray(const CString &name, Value *value); + Variable &appendToArray(const String &name, Value *value); /** * Inserts a value to an array variable. The array is assumed to be sorted, and the @@ -455,7 +452,7 @@ class DE_PUBLIC Record * @param name Name of the variable. * @param value Value to insert. */ - Variable &insertToSortedArray(const CString &name, Value *value); + Variable &insertToSortedArray(const String &name, Value *value); /** * Looks up a variable in the record. Variables in subrecords can be accessed @@ -465,7 +462,7 @@ class DE_PUBLIC Record * * @return Variable. */ - Variable &operator[](const CString &name); + Variable &operator[](const String &name); /** * Looks up a variable in the record. Variables in subrecords can be accessed @@ -475,17 +472,17 @@ class DE_PUBLIC Record * * @return Variable (non-modifiable). */ - const Variable &operator[](const CString &name) const; + const Variable &operator[](const String &name) const; - Variable *tryFind(const CString &name); + Variable *tryFind(const String &name); - Variable const *tryFind(const CString &name) const; + Variable const *tryFind(const String &name) const; - inline Variable &member(const CString &name) { + inline Variable &member(const String &name) { return (*this)[name]; } - inline Variable const &member(const CString &name) const { + inline Variable const &member(const String &name) const { return (*this)[name]; } @@ -496,7 +493,7 @@ class DE_PUBLIC Record * * @return Subrecord. */ - Record &subrecord(const CString &name); + Record &subrecord(const String &name); /** * Looks up a subrecord in the record. @@ -505,7 +502,7 @@ class DE_PUBLIC Record * * @return Subrecord (non-modifiable). */ - Record const &subrecord(const CString &name) const; + Record const &subrecord(const String &name) const; dsize size() const; @@ -570,7 +567,7 @@ class DE_PUBLIC Record * @return Value cast to a specific value type. */ template - ValueType const &value(const CString &name) const { + ValueType const &value(const String &name) const { return (*this)[name].value(); } @@ -584,7 +581,7 @@ class DE_PUBLIC Record * * @return The function instance. */ - Function const &function(const CString &name) const; + Function const &function(const String &name) const; /** * Adds a new record to be used as a superclass of this record. @@ -618,7 +615,7 @@ class DE_PUBLIC Record * * @return Record containing the @a name. */ - Record const &parentRecordForMember(const CString &name) const; + Record const &parentRecordForMember(const String &name) const; String asInfo() const; diff --git a/doomsday/libs/core/include/de/data/recordaccessor.h b/doomsday/libs/core/include/de/data/recordaccessor.h index 62510294f9..503f574410 100644 --- a/doomsday/libs/core/include/de/data/recordaccessor.h +++ b/doomsday/libs/core/include/de/data/recordaccessor.h @@ -51,29 +51,29 @@ class DE_PUBLIC RecordAccessor Record const &accessedRecord() const; Record const *accessedRecordPtr() const; - bool has(const char *name) const; - Value const &get(const char *name) const; - dint geti(const char *name) const; - dint geti(const char *name, dint defaultValue) const; - bool getb(const char *name) const; - bool getb(const char *name, bool defaultValue) const; - duint getui(const char *name) const; - duint getui(const char *name, duint defaultValue) const; - dfloat getf(const char *name) const; - dfloat getf(const char *name, dfloat defaultValue) const; - ddouble getd(const char *name) const; - ddouble getd(const char *name, ddouble defaultValue) const; - String gets(const char *name) const; - String gets(const char *name, String const &defaultValue) const; - ArrayValue const &geta(const char *name) const; - DictionaryValue const &getdt(const char *name) const; - RecordValue const &getr(const char *name) const; - StringList getStringList(const char *name, StringList defaultValue = StringList()) const; + bool has(const String &name) const; + Value const &get(const String &name) const; + dint geti(const String &name) const; + dint geti(const String &name, dint defaultValue) const; + bool getb(const String &name) const; + bool getb(const String &name, bool defaultValue) const; + duint getui(const String &name) const; + duint getui(const String &name, duint defaultValue) const; + dfloat getf(const String &name) const; + dfloat getf(const String &name, dfloat defaultValue) const; + ddouble getd(const String &name) const; + ddouble getd(const String &name, ddouble defaultValue) const; + String gets(const String &name) const; + String gets(const String &name, const char *defaultValue) const; + ArrayValue const &geta(const String &name) const; + DictionaryValue const &getdt(const String &name) const; + RecordValue const &getr(const String &name) const; + StringList getStringList(const String &name, StringList defaultValue = StringList()) const; - Record const &subrecord(const char *name) const; + Record const &subrecord(const String &name) const; template - ValueType const &getAs(const char *name) const { + ValueType const &getAs(const String &name) const { ValueType const *v = maybeAs(get(name)); if (!v) { throw ValueTypeError("RecordAccessor::getAs", String("Cannot cast to expected type (") + diff --git a/doomsday/libs/core/include/de/data/string.h b/doomsday/libs/core/include/de/data/string.h index 596e429df6..5e61f49caf 100644 --- a/doomsday/libs/core/include/de/data/string.h +++ b/doomsday/libs/core/include/de/data/string.h @@ -206,6 +206,7 @@ class DE_PUBLIC String : public IByteArray return {constBegin_String(&_str), constEnd_String(&_str)}; } std::wstring toWideString() const; + CString toCString() const; void clear(); @@ -216,6 +217,7 @@ class DE_PUBLIC String : public IByteArray Char last() const; bool contains(const char *cStr) const; + int count(char ch) const; bool beginsWith(const String &s, CaseSensitivity cs = CaseSensitive) const { @@ -272,8 +274,11 @@ class DE_PUBLIC String : public IByteArray String &append(const char *s) { return *this += s; } String &append(const String &s) { return *this += s; } + inline void push_back(Char ch) { append(ch); } + void insert(BytePos pos, const char *cStr); void insert(BytePos pos, const String &str); + String &replace(Char before, Char after); String &replace(const CString &before, const CString &after); /** @@ -297,6 +302,8 @@ class DE_PUBLIC String : public IByteArray */ String operator/(const String &path) const; + String operator/(const CString &path) const; + /** * Applies pattern formatting using the string as a format string. * diff --git a/doomsday/libs/core/include/de/data/stringpool.h b/doomsday/libs/core/include/de/data/stringpool.h index 48d0d88596..5f04666f70 100644 --- a/doomsday/libs/core/include/de/data/stringpool.h +++ b/doomsday/libs/core/include/de/data/stringpool.h @@ -109,7 +109,7 @@ class DE_PUBLIC StringPool : public ISerializable * * @return Unique Id associated with the internal copy of @a str. */ - Id intern(String str); + Id intern(const String &str); /** * Interns string @a str. If this string is not already in the pool, a new @@ -121,7 +121,7 @@ class DE_PUBLIC StringPool : public ISerializable * * @return The interned copy of the string owned by the pool. */ - String internAndRetrieve(String str); + String internAndRetrieve(const String &str); /** * Sets the user-specified custom value associated with the string @a id. @@ -169,7 +169,7 @@ class DE_PUBLIC StringPool : public ISerializable * * @return Id of the matching string; else @c 0. */ - Id isInterned(String str) const; + Id isInterned(const String &str) const; /** * Retrieve an immutable copy of the interned string associated with the @@ -200,7 +200,7 @@ class DE_PUBLIC StringPool : public ISerializable * * @return @c true iff a string was removed. */ - bool remove(String str); + bool remove(const String &str); /** * Removes a string from the pool. diff --git a/doomsday/libs/core/include/de/data/value.h b/doomsday/libs/core/include/de/data/value.h index 26783dc6c1..c388e4e242 100644 --- a/doomsday/libs/core/include/de/data/value.h +++ b/doomsday/libs/core/include/de/data/value.h @@ -312,7 +312,7 @@ class DE_PUBLIC Value : public Deletable, public String::IPatternArg, public ISe */ static Value *constructFrom(Reader &reader); - /** + /* * Construct a value by converting from a QVariant. * @param variant Data for the value. * @return Value. Caller gets ownership. diff --git a/doomsday/libs/core/include/de/data/variable.h b/doomsday/libs/core/include/de/data/variable.h index 5f59476566..1f0261a331 100644 --- a/doomsday/libs/core/include/de/data/variable.h +++ b/doomsday/libs/core/include/de/data/variable.h @@ -114,7 +114,7 @@ class DE_PUBLIC Variable : public Deletable, public ISerializable * a NoneValue will be created for the variable. * @param varMode Mode flags. */ - Variable(const CString &name = {}, Value *initial = nullptr, + Variable(const String &name = {}, Value *initial = nullptr, Flags const &varMode = DefaultMode); /** diff --git a/doomsday/libs/core/include/de/filesys/fileindex.h b/doomsday/libs/core/include/de/filesys/fileindex.h index 772b1be2c3..256a1ca32c 100644 --- a/doomsday/libs/core/include/de/filesys/fileindex.h +++ b/doomsday/libs/core/include/de/filesys/fileindex.h @@ -93,7 +93,7 @@ class DE_PUBLIC FileIndex enum Behavior { FindInEntireIndex, FindOnlyInLoadedPackages }; - void findPartialPath(const CString &path, FoundFiles &found, + void findPartialPath(const String &path, FoundFiles &found, Behavior behavior = FindInEntireIndex) const; /** @@ -106,7 +106,7 @@ class DE_PUBLIC FileIndex * @param behavior Search behavior. */ void findPartialPath(Folder const &rootFolder, - const CString &path, + const String &path, FoundFiles &found, Behavior behavior = FindInEntireIndex) const; @@ -117,8 +117,8 @@ class DE_PUBLIC FileIndex * @param path Partial path to find. * @param found All matching files. */ - void findPartialPath(const CString &packageId, - const CString &path, + void findPartialPath(const String &packageId, + const String &path, FoundFiles &found) const; /** @@ -136,7 +136,7 @@ class DE_PUBLIC FileIndex * * @return Number of files found. */ - int findPartialPathInPackageOrder(const CString &path, FoundFiles &found, + int findPartialPathInPackageOrder(const String &path, FoundFiles &found, Behavior behavior = FindOnlyInLoadedPackages) const; void print() const; diff --git a/doomsday/libs/core/include/de/libcore.h b/doomsday/libs/core/include/de/libcore.h index f3bae99003..2216ac43b7 100644 --- a/doomsday/libs/core/include/de/libcore.h +++ b/doomsday/libs/core/include/de/libcore.h @@ -204,6 +204,19 @@ #define DENG2_OFFSET_PTR(type, member) \ reinterpret_cast(offsetof(type, member)) +/** + * Returns a String literal that uses statically allocated memory + * for the string. + */ +#define DE_STR(cStringLiteral) \ + ([]() -> de::String { \ + const size_t len = std::strlen(cStringLiteral); /* likely compile time */ \ + static iBlockData blockData = { \ + 2, const_cast(cStringLiteral), len, len + 1}; \ + static iBlock block = { &blockData }; \ + return de::String(&block); \ + }()) + /** * Macro for defining an opaque type in the C wrapper API. */ diff --git a/doomsday/libs/core/include/de/scriptsys/iobject.h b/doomsday/libs/core/include/de/scriptsys/iobject.h index 9be2c9ba88..00c36841e7 100644 --- a/doomsday/libs/core/include/de/scriptsys/iobject.h +++ b/doomsday/libs/core/include/de/scriptsys/iobject.h @@ -59,7 +59,7 @@ class DE_PUBLIC IObject * * @return Variable. */ - inline Variable &operator [] (const CString &name) { + inline Variable &operator [] (const String &name) { return objectNamespace()[name]; } @@ -73,7 +73,7 @@ class DE_PUBLIC IObject * * @return Variable. */ - inline Variable const &operator [] (const CString name) const { + inline Variable const &operator [] (const String &name) const { return objectNamespace()[name]; } }; diff --git a/doomsday/libs/core/src/core/app.cpp b/doomsday/libs/core/src/core/app.cpp index bad9c4c54e..ca0f735f12 100644 --- a/doomsday/libs/core/src/core/app.cpp +++ b/doomsday/libs/core/src/core/app.cpp @@ -399,7 +399,7 @@ DE_PIMPL(App) fs.root().locate("/packs").populate(); } - Record const *findAsset(const CString &identifier) const + Record const *findAsset(const String &identifier) const { // Access the package that has this asset via a link. Folder const *pkg = fs.root().tryLocate(String("/packs/asset.") + identifier + "/."); @@ -919,17 +919,17 @@ PackageLoader &App::packageLoader() return DE_APP->d->packageLoader; } -int App::findInPackages(const CString &partialPath, FS::FoundFiles &files) +int App::findInPackages(const String &partialPath, FS::FoundFiles &files) { return App::fileSystem().nameIndex().findPartialPathInPackageOrder(partialPath, files); } -bool App::assetExists(const CString &identifier) +bool App::assetExists(const String &identifier) { return DE_APP->d->findAsset(identifier) != 0; } -Package::Asset App::asset(const CString &identifier) +Package::Asset App::asset(const String &identifier) { Record const *info = DE_APP->d->findAsset(identifier); if (!info) @@ -971,7 +971,7 @@ Config &App::config() return *DE_APP->d->config; } -Variable &App::config(const CString &name) +Variable &App::config(const String &name) { return config()[name]; } diff --git a/doomsday/libs/core/src/core/config.cpp b/doomsday/libs/core/src/core/config.cpp index 9e0ea285bc..3a7877047b 100644 --- a/doomsday/libs/core/src/core/config.cpp +++ b/doomsday/libs/core/src/core/config.cpp @@ -218,7 +218,7 @@ Config &Config::get() return App::config(); } -Variable &Config::get(const CString &name) // static +Variable &Config::get(const String &name) // static { return get()[name]; } @@ -233,32 +233,32 @@ Version Config::upgradedFromVersion() const return d->oldVersion; } -Variable &Config::set(const CString &name, bool value) +Variable &Config::set(const String &name, bool value) { return objectNamespace().set(name, value); } -Variable &Config::set(const CString &name, Value::Number const &value) +Variable &Config::set(const String &name, Value::Number const &value) { return objectNamespace().set(name, value); } -Variable &Config::set(const CString &name, dint value) +Variable &Config::set(const String &name, dint value) { return objectNamespace().set(name, value); } -Variable &Config::set(const CString &name, duint value) +Variable &Config::set(const String &name, duint value) { return objectNamespace().set(name, value); } -Variable &Config::set(const CString &name, ArrayValue *value) +Variable &Config::set(const String &name, ArrayValue *value) { return objectNamespace().set(name, value); } -Variable &Config::set(const CString &name, Value::Text const &value) +Variable &Config::set(const String &name, Value::Text const &value) { return objectNamespace().set(name, value); } diff --git a/doomsday/libs/core/src/core/library.cpp b/doomsday/libs/core/src/core/library.cpp index 6da2d5e0ef..4b2a24e804 100644 --- a/doomsday/libs/core/src/core/library.cpp +++ b/doomsday/libs/core/src/core/library.cpp @@ -209,7 +209,7 @@ void *Library::address(String const &name, SymbolLookupMode lookup) return 0; } - d->symbols[name] = ptr; + d->symbols.insert(name, ptr); return ptr; } diff --git a/doomsday/libs/core/src/data/block.cpp b/doomsday/libs/core/src/data/block.cpp index b8f1df5bb9..e6cd567eb3 100644 --- a/doomsday/libs/core/src/data/block.cpp +++ b/doomsday/libs/core/src/data/block.cpp @@ -57,6 +57,11 @@ Block::Block(const char *nullTerminatedCStr) initCStr_Block(&_block, nullTerminatedCStr); } +Block::Block(const std::string &str) +{ + initData_Block(&_block, str.data(), str.size()); +} + Block::Block(const void *data, Size length) { initData_Block(&_block, data, length); diff --git a/doomsday/libs/core/src/data/info.cpp b/doomsday/libs/core/src/data/info.cpp index af46cbb895..d12a87ae2d 100644 --- a/doomsday/libs/core/src/data/info.cpp +++ b/doomsday/libs/core/src/data/info.cpp @@ -31,7 +31,7 @@ namespace de { -static const char *WHITESPACE = " \t\r\n"; +//static const char *WHITESPACE = " \t\r\n"; static const char *WHITESPACE_OR_COMMENT = " \t\r\n#"; static const char *TOKEN_BREAKING_CHARS = "#:=$(){}<>,;\" \t\r\n"; static const char *INCLUDE_TOKEN = "@include"; diff --git a/doomsday/libs/core/src/data/path.cpp b/doomsday/libs/core/src/data/path.cpp index 68a450dbbc..3e445a6da8 100644 --- a/doomsday/libs/core/src/data/path.cpp +++ b/doomsday/libs/core/src/data/path.cpp @@ -29,8 +29,6 @@ namespace de { /// Size of the fixed-size portion of the segment buffer. static int const SEGMENT_BUFFER_SIZE = 8; -static String emptyPath; - //--------------------------------------------------------------------------------------- Path::hash_type const Path::hash_range = 0xffffffff; @@ -92,10 +90,13 @@ dsize Path::Segment::size() const DE_PIMPL_NOREF(Path) { + static String emptyPath; + String path; - /// The character in Impl::path that acts as the segment separator. - Char separator; + /// The character(s) in Impl::path that act(s) as the segment separator. + /// This is assumed to be a single multibyte character. + String separator; /** * Total number of segments in the path. If 0, it means that the path @@ -126,10 +127,21 @@ DE_PIMPL_NOREF(Path) */ List extraSegments; - Impl() : separator('/'), segmentCount(0) + Impl() + : separator("/") + , segmentCount(0) + {} + + Impl(const String &p, const String &sep) + : path(p) + , separator(sep) + , segmentCount(0) {} - Impl(String const &p, Char sep) : path(p), separator(sep), segmentCount(0) + Impl(const String &p, Char sep) + : path(p) + , separator(1, sep) + , segmentCount(0) {} ~Impl() @@ -155,7 +167,7 @@ DE_PIMPL_NOREF(Path) * * @return New segment. */ - Path::Segment *allocSegment(QStringRef const &range) + Path::Segment *allocSegment(const String &range) { Path::Segment *segment; if (segmentCount < SEGMENT_BUFFER_SIZE) @@ -246,12 +258,12 @@ Path::Path(String const &path, Char sep) : d(new Impl(path, sep)) {} -Path::Path(char const *nullTerminatedCStr, char sep) - : d(new Impl(QString::fromUtf8(nullTerminatedCStr), sep)) +Path::Path(char const *nullTerminatedCStr, Char sep) + : d(new Impl(nullTerminatedCStr, sep)) {} Path::Path(char const *nullTerminatedCStr) - : d(new Impl(QString::fromUtf8(nullTerminatedCStr), '/')) + : d(new Impl(nullTerminatedCStr, '/')) {} Path::Path(Path const &other) @@ -281,12 +293,12 @@ Path &Path::operator=(Path &&moved) Path Path::operator+(String const &str) const { - return Path(d->path + str, d->separator); + return Path(d->path + str, d->separator.first()); } Path Path::operator+(char const *nullTerminatedCStr) const { - return Path(d->path + QString(nullTerminatedCStr), d->separator); + return Path(d->path + nullTerminatedCStr, d->separator.first()); } int Path::segmentCount() const @@ -307,7 +319,8 @@ Path::Segment const &Path::reverseSegment(int reverseIndex) const if (reverseIndex < 0 || reverseIndex >= d->segmentCount) { /// @throw OutOfBoundsError Attempt to reference a nonexistent segment. - throw OutOfBoundsError("Path::reverseSegment", String("Reverse index %1 is out of bounds").arg(reverseIndex)); + throw OutOfBoundsError("Path::reverseSegment", + stringf("Reverse index %i is out of bounds", reverseIndex)); } // Is this in the static buffer? @@ -324,9 +337,9 @@ Path Path::subPath(Rangei const &range) const { if (range.isEmpty()) { - return Path("", d->separator); + return Path("", d->separator.first()); } - Path sub(segment(range.start), d->separator); + Path sub(String(segment(range.start)), d->separator.first()); for (int i = range.start + 1; i < range.end; ++i) { sub = sub / segment(i); @@ -393,16 +406,17 @@ bool Path::operator < (Path const &other) const } } -Path Path::operator/(Path const &other) const +Path Path::operator/(const Path &other) const { // Unify the separators. String otherPath = other.d->path; - if (other.separator() != d->separator) + if (other.d->separator != d->separator) { otherPath.replace(other.d->separator, d->separator); } - return Path(d->path.concatenatePath(otherPath, d->separator), d->separator); + const Char sep = d->separator.first(); + return Path(d->path.concatenatePath(otherPath, sep), sep); } Path Path::operator/(const String &other) const @@ -410,16 +424,11 @@ Path Path::operator/(const String &other) const return *this / Path(other); } -Path Path::operator/(char const *otherNullTerminatedUtf8) const +Path Path::operator/(const char *otherNullTerminatedUtf8) const { return *this / Path(otherNullTerminatedUtf8, '/'); } -Path Path::operator/(String const &other) const -{ - return *this / Path(other); -} - String Path::toString() const { return d->path; @@ -447,7 +456,7 @@ bool Path::isAbsolute() const int Path::length() const { - return d->path.length(); + return d->path.size(); } dsize Path::size() const @@ -481,30 +490,31 @@ Path &Path::operator = (String const &newPath) Path &Path::set(String const &newPath, Char sep) { d->path = newPath; // implicitly shared - d->separator = sep; + d->separator = String(1, sep); d->clearSegments(); return *this; } Path Path::withSeparators(Char sep) const { - if (sep == d->separator) return *this; + const Char curSep = d->separator.first(); + if (sep == curSep) return *this; String modPath = d->path; - modPath.replace(d->separator, sep); + modPath.replace(d->separator, String(1, sep)); return Path(modPath, sep); } Char Path::separator() const { - return d->separator; + return d->separator.first(); } void Path::addTerminatingSeparator() { if (!isEmpty()) { - if (last() != d->separator) + if (last() != d->separator.first()) { d->path.append(d->separator); d->clearSegments(); @@ -514,8 +524,8 @@ void Path::addTerminatingSeparator() String Path::fileName() const { - if (last() == d->separator) return ""; - return lastSegment(); + if (last() == d->separator.first()) return ""; + return lastSegment().toRange(); } Block Path::toUtf8() const @@ -525,7 +535,7 @@ Block Path::toUtf8() const void Path::operator >> (Writer &to) const { - to << d->path.toUtf8() << d->separator.unicode(); + to << d->path << duint16(d->separator.first()); } void Path::operator << (Reader &from) @@ -533,9 +543,9 @@ void Path::operator << (Reader &from) clear(); Block b; - ushort sep; + duint16 sep; from >> b >> sep; - set(String::fromUtf8(b), sep); + set(String::fromUtf8(b), Char(sep)); } String Path::normalizeString(String const &text, Char replaceWith) @@ -561,7 +571,7 @@ Path PathRef::toPath() const { if (!segmentCount()) return Path(); // Empty. - String composed = segment(0); + String composed = segment(0).toRange(); for (int i = 1; i < segmentCount(); ++i) { composed += path().separator(); @@ -572,6 +582,7 @@ Path PathRef::toPath() const } // namespace de +#if 0 #ifdef _DEBUG #include @@ -720,3 +731,4 @@ static int Path_UnitTest() static int testResult = Path_UnitTest(); #endif // _DEBUG +#endif diff --git a/doomsday/libs/core/src/data/pathtree.cpp b/doomsday/libs/core/src/data/pathtree.cpp index 26ff650993..7f346035db 100644 --- a/doomsday/libs/core/src/data/pathtree.cpp +++ b/doomsday/libs/core/src/data/pathtree.cpp @@ -67,7 +67,7 @@ struct PathTree::Impl DE_ASSERT(numNodesOwned == 0); } - PathTree::SegmentId internSegmentAndUpdateIdHashMap(String segment, Path::hash_type hashKey) + PathTree::SegmentId internSegmentAndUpdateIdHashMap(const String &segment, Path::hash_type hashKey) { PathTree::SegmentId internId = segments.intern(segment); segments.setUserValue(internId, hashKey); @@ -90,7 +90,7 @@ struct PathTree::Impl // The name is known. Perhaps we have. Path::hash_type hashKey = segments.userValue(segmentId); for (PathTree::Nodes::const_iterator i = hash.find(hashKey); - i != hash.end() && i.key() == hashKey; ++i) + i != hash.end() && i.key() == hashKey; ++i) { PathTree::Node *node = *i; if (parent != &node->parent()) continue; diff --git a/doomsday/libs/core/src/data/pathtreenode.cpp b/doomsday/libs/core/src/data/pathtreenode.cpp index 13ab6cd1cd..e7ffe8d2c7 100644 --- a/doomsday/libs/core/src/data/pathtreenode.cpp +++ b/doomsday/libs/core/src/data/pathtreenode.cpp @@ -143,8 +143,8 @@ Path::hash_type PathTree::Node::hash() const } /// @todo This logic should be encapsulated in de::Path or de::Path::Segment. -static int matchName(QChar const *string, dsize stringSize, - QChar const *pattern, dsize patternSize) +static int matchName(char const *string, dsize stringSize, + char const *pattern, dsize patternSize) { QChar const *in = string; QChar const *inEnd = string + stringSize; diff --git a/doomsday/libs/core/src/data/profiles.cpp b/doomsday/libs/core/src/data/profiles.cpp index 42902d9b20..2cdf09c73f 100644 --- a/doomsday/libs/core/src/data/profiles.cpp +++ b/doomsday/libs/core/src/data/profiles.cpp @@ -24,15 +24,15 @@ namespace de { -static String nameToKey(String const &name) +static String nameToKey(const String &name) { - return name.toLower(); + return name.lower(); } DE_PIMPL(Profiles) , DE_OBSERVES(Deletable, Deletion) { - typedef QMap Profiles; + typedef Map Profiles; Profiles profiles; String persistentName; @@ -82,7 +82,7 @@ DE_PIMPL(Profiles) void objectWasDeleted(Deletable *obj) { // At this point the AbstractProfile itself is already deleted. - QMutableMapIterator iter(profiles); + MutableMapIterator iter(profiles); while (iter.hasNext()) { iter.next(); @@ -96,12 +96,12 @@ DE_PIMPL(Profiles) void clear() { - for (auto *prof : profiles) + for (auto &prof : profiles) { - prof->audienceForDeletion -= this; - prof->setOwner(nullptr); + prof.second->audienceForDeletion -= this; + prof.second->setOwner(nullptr); + delete prof.second; } - qDeleteAll(profiles.values()); profiles.clear(); } @@ -112,7 +112,7 @@ DE_PIMPL(Profiles) String fileName() const { if (persistentName.isEmpty()) return ""; - return String("/home/configs/%1.dei").arg(persistentName); + return String::format("/home/configs/%s.dei", persistentName.c_str()); } void loadProfilesFromInfo(File const &file, bool markReadOnly) @@ -127,7 +127,7 @@ DE_PIMPL(Profiles) de::Info info; info.parse(String::fromUtf8(raw)); - foreach (de::Info::Element const *elem, info.root().contentsInOrder()) + for (const auto *elem : info.root().contentsInOrder()) { if (!elem->isBlock()) continue; @@ -171,7 +171,7 @@ Profiles::~Profiles() StringList Profiles::profiles() const { StringList names; - for (auto const *p : d->profiles.values()) names << p->name(); + for (auto &p : d->profiles) names << p.second->name(); return names; } @@ -182,10 +182,10 @@ int Profiles::count() const Profiles::AbstractProfile *Profiles::tryFind(String const &name) const { - auto found = d->profiles.constFind(nameToKey(name)); - if (found != d->profiles.constEnd()) + auto found = d->profiles.find(nameToKey(name)); + if (found != d->profiles.end()) { - return found.value(); + return found->second; } return nullptr; } @@ -216,9 +216,9 @@ bool Profiles::isPersistent() const LoopResult Profiles::forAll(std::function func) const { - foreach (AbstractProfile *prof, d->profiles.values()) + for (const auto &prof : d->profiles) { - if (auto result = func(*prof)) + if (auto result = func(*prof.second)) { return result; } @@ -264,8 +264,9 @@ void Profiles::serialize() const // Write /home/configs/(persistentName).dei with all non-readonly profiles. int count = 0; - for (auto *prof : d->profiles) + for (auto &iter : d->profiles) { + const auto *prof = iter.second; if (prof->isReadOnly()) continue; os << "\nprofile {\n" @@ -280,7 +281,7 @@ void Profiles::serialize() const // Create the pack and update the file system. File &outFile = App::rootFolder().replaceFile(d->fileName()); - outFile << Block(os.str(), os.str().size()); + outFile << Block(os.str()); outFile.flush(); // we're done LOG_VERBOSE("Wrote \"%s\" with %i profile%s") diff --git a/doomsday/libs/core/src/data/record.cpp b/doomsday/libs/core/src/data/record.cpp index 1038bcad94..e154f13cc8 100644 --- a/doomsday/libs/core/src/data/record.cpp +++ b/doomsday/libs/core/src/data/record.cpp @@ -27,6 +27,7 @@ #include "de/NumberValue" #include "de/Reader" #include "de/RecordValue" +#include "de/RegExp" #include "de/String" #include "de/TextValue" #include "de/TimeValue" @@ -36,9 +37,9 @@ #include "de/CompiledRecord" -#include #include #include +#include namespace de { @@ -47,10 +48,10 @@ namespace de { /// excerpt. int const SUBRECORD_CONTENT_EXCERPT_THRESHOLD = 100; // lines -String const Record::VAR_SUPER = "__super__"; -String const Record::VAR_FILE = "__file__"; -String const Record::VAR_INIT = "__init__"; -String const Record::VAR_NATIVE_SELF = "__self__"; +const char *Record::VAR_SUPER = "__super__"; +const char *Record::VAR_FILE = "__file__"; +const char *Record::VAR_INIT = "__init__"; +const char *Record::VAR_NATIVE_SELF = "__self__"; /** * Each record is given a unique identifier, so that serialized record @@ -67,7 +68,7 @@ DE_PIMPL(Record) duint32 oldUniqueId; Flags flags = DefaultFlags; - typedef QHash RefMap; + typedef Hash RefMap; Impl(Public &r) : Base(r) @@ -80,14 +81,14 @@ DE_PIMPL(Record) ExcludeByBehavior(Behavior b) : behavior(b) {} bool operator () (Variable const &member) { return (behavior == IgnoreDoubleUnderscoreMembers && - member.name().startsWith("__")); + member.name().beginsWith("__")); } }; struct ExcludeByRegExp { - QRegExp omitted; - ExcludeByRegExp(QRegExp const &omit) : omitted(omit) {} - bool operator () (Variable const &member) { + RegExp omitted; + ExcludeByRegExp(const RegExp &omit) : omitted(omit) {} + bool operator()(const Variable &member) { return omitted.exactMatch(member.name()); } }; @@ -98,18 +99,18 @@ DE_PIMPL(Record) { Record::Members remaining; // Contains all members that are not removed. - DE_FOR_EACH(Members, i, members) + for (auto &i : members) { - if (excluded(*i.value())) + if (excluded(*i.second)) { - remaining.insert(i.key(), i.value()); + remaining.insert(i.first, i.second); continue; } - DE_FOR_PUBLIC_AUDIENCE2(Removal, o) o->recordMemberRemoved(self(), **i); + DE_FOR_PUBLIC_AUDIENCE2(Removal, o) o->recordMemberRemoved(self(), *i.second); - i.value()->audienceForDeletion() -= this; - delete i.value(); + i.second->audienceForDeletion() -= this; + delete i.second; } members = remaining; @@ -121,27 +122,30 @@ DE_PIMPL(Record) auto const *other_d = other.d.getConst(); DE_GUARD(other_d); - DE_FOR_EACH_CONST(Members, i, other_d->members) + for (auto &i : other_d->members) { - if (!excluded(*i.value())) + const auto &i_key = i.first; + const auto *i_value = i.second; + + if (!excluded(*i_value)) { bool alreadyExists; Variable *var; { DE_GUARD(this); - var = new Variable(*i.value()); + var = new Variable(*i_value); var->audienceForDeletion() += this; - auto iter = members.find(i.key()); + auto iter = members.find(i_key); alreadyExists = (iter != members.end()); if (alreadyExists) { - iter.value()->audienceForDeletion() -= this; - delete iter.value(); - iter.value() = var; + iter->second->audienceForDeletion() -= this; + delete iter->second; + iter->second = var; } else { - members[i.key()] = var; + members[i_key] = var; } } @@ -164,37 +168,37 @@ DE_PIMPL(Record) // Add variables or update existing ones. for (auto i = other_d->members.begin(); i != other_d->members.end(); ++i) { - if (!excluded(*i.value())) + if (!excluded(*i->second)) { Variable *var = nullptr; // Already have a variable with this name? { DE_GUARD(this); - auto found = members.constFind(i.key()); - if (found != members.constEnd()) + auto found = members.find(i->first); + if (found != members.end()) { - var = found.value(); + var = found->second; } } // Change the existing value. if (var) { - if (isSubrecord(*i.value()) && isSubrecord(*var)) + if (isSubrecord(*i->second) && isSubrecord(*var)) { // Recurse to subrecords. var->valueAsRecord().d->assignPreservingVariables - (i.value()->valueAsRecord(), excluded); + (i->second->valueAsRecord(), excluded); } else { // Ignore read-only flags. - Variable::Flags const oldFlags = var->flags(); + Flags const oldFlags = var->flags(); var->setFlags(Variable::ReadOnly, false); // Just make a copy. - var->set(i.value()->value()); + var->set(i->second->value()); var->setFlags(oldFlags, ReplaceFlags); } @@ -203,16 +207,16 @@ DE_PIMPL(Record) { // Add a new one. DE_GUARD(this); - var = new Variable(*i.value()); + var = new Variable(*i->second); var->audienceForDeletion() += this; - members[i.key()] = var; + members[i->first] = var; } } } // Remove variables not present in the other. DE_GUARD(this); - QMutableHashIterator iter(members); + MutableHashIterator iter(members); while (iter.hasNext()) { iter.next(); @@ -243,15 +247,15 @@ DE_PIMPL(Record) LoopResult forSubrecords(std::function func) const { Members const unmodifiedMembers = members; // In case a callback removes members. - DE_FOR_EACH_CONST(Members, i, unmodifiedMembers) + for (auto &i : unmodifiedMembers) { - Variable const &member = *i.value(); + Variable const &member = *i.second; if (isSubrecord(member)) { Record *rec = member.value().record(); DE_ASSERT(rec != 0); // subrecords are owned, so cannot have been deleted - if (auto result = func(i.key(), *rec)) + if (auto result = func(i.first, *rec)) { return result; } @@ -265,39 +269,36 @@ DE_PIMPL(Record) DE_GUARD(this); Subrecords subs; - forSubrecords([&subs, filter] (const CString &, Record &rec) + forSubrecords([&subs, filter] (const String &name, Record &rec) { // Must pass the filter. if (filter(rec)) { - subs.insert(name, &rec); + subs.insert(String(name), &rec); } return LoopContinue; }); return subs; } - Variable const *findMemberByPath(const CString &name) const + Variable const *findMemberByPath(const String &name) const { // Path notation allows looking into subrecords. - int pos = name.indexOf('.'); - if (pos >= 0) + if (auto pos = name.indexOf('.')) { - CString subName = name.substr(0, pos); - CString remaining = name.substr(pos + 1); + String subName = name.left(pos); + String remaining = name.substr(pos + 1); // If it is a subrecord we can descend into it. if (!self().hasRecord(subName)) return 0; return self()[subName].value().dereference().d->findMemberByPath(remaining); } DE_GUARD(this); - - Members::const_iterator found = members.constFind(name); - if (found != members.constEnd()) + auto found = members.find(name); + if (found != members.end()) { - return found.value(); + return found->second; } - return 0; } @@ -309,15 +310,14 @@ DE_PIMPL(Record) * * @return Parent record for the variable. */ - Record &parentRecordByPath(const CString &pathOrName) + Record &parentRecordByPath(const String &pathOrName) { DE_GUARD(this); - int pos = pathOrName.indexOf('.'); - if (pos >= 0) + if (auto pos = pathOrName.indexOf('.')) { - CString subName = pathOrName.substr(0, pos); - CString remaining = pathOrName.substr(pos + 1); + String subName = pathOrName.left(pos); + String remaining = pathOrName.substr(pos + 1); Record *rec = 0; if (!self().hasSubrecord(subName)) @@ -347,9 +347,9 @@ DE_PIMPL(Record) members.remove(variable.name()); } - static String memberNameFromPath(const CString &path) + static String memberNameFromPath(const String &path) { - return path.fileName('.'); + return String(path).fileName('.'); /// @todo Should not copying `path`. } /** @@ -364,9 +364,9 @@ DE_PIMPL(Record) */ void reconnectReferencesAfterDeserialization(RefMap const &refMap) { - DE_FOR_EACH(Members, i, members) + for (auto &i : members) { - RecordValue *value = dynamic_cast(&i.value()->value()); + RecordValue *value = dynamic_cast(&i.second->value()); if (!value || !value->record()) continue; // Recurse into subrecords first. @@ -438,7 +438,7 @@ Record &Record::setFlags(Flags flags, FlagOpArg op) return *this; } -Record::Flags Record::flags() const +Flags Record::flags() const { return d->flags; } @@ -483,7 +483,7 @@ Record &Record::assign(Record const &other, Behavior behavior) return *this; } -Record &Record::assign(Record const &other, QRegExp const &excluded) +Record &Record::assign(Record const &other, const RegExp &excluded) { DE_GUARD(d); @@ -492,23 +492,23 @@ Record &Record::assign(Record const &other, QRegExp const &excluded) return *this; } -bool Record::has(const CString &name) const +bool Record::has(const String &name) const { return hasMember(name); } -bool Record::hasMember(const CString &variableName) const +bool Record::hasMember(const String &variableName) const { return d->findMemberByPath(variableName) != 0; } -bool Record::hasSubrecord(const CString &subrecordName) const +bool Record::hasSubrecord(const String &subrecordName) const { Variable const *found = d->findMemberByPath(subrecordName); return found? d->isSubrecord(*found) : false; } -bool Record::hasRecord(const CString &recordName) const +bool Record::hasRecord(const String &recordName) const { Variable const *found = d->findMemberByPath(recordName); return found? d->isRecord(*found) : false; @@ -552,12 +552,12 @@ Variable *Record::remove(Variable &variable) return &variable; } -Variable *Record::remove(const char *variableName) +Variable *Record::remove(const String &variableName) { return remove((*this)[variableName]); } -Variable *Record::tryRemove(const CString &variableName) +Variable *Record::tryRemove(const String &variableName) { if (has(variableName)) { @@ -566,45 +566,45 @@ Variable *Record::tryRemove(const CString &variableName) return nullptr; } -Variable &Record::add(const CString &name, Variable::Flags variableFlags) +Variable &Record::add(const String &name, Variable::Flags variableFlags) { return d->parentRecordByPath(name) .add(new Variable(Impl::memberNameFromPath(name), nullptr, variableFlags)); } -Variable &Record::addNumber(const CString &name, Value::Number number) +Variable &Record::addNumber(const String &name, Value::Number number) { return add(name, Variable::AllowNumber).set(NumberValue(number)); } -Variable &Record::addBoolean(const CString &, bool booleanValue) +Variable &Record::addBoolean(const String &name, bool booleanValue) { return add(name, Variable::AllowNumber).set(NumberValue(booleanValue, NumberValue::Boolean)); } -Variable &Record::addText(const CString &, Value::Text const &text) +Variable &Record::addText(const String &name, Value::Text const &text) { return add(name, Variable::AllowText).set(TextValue(text)); } -Variable &Record::addTime(const CString &, Time const &time) +Variable &Record::addTime(const String &name, Time const &time) { return add(name, Variable::AllowTime).set(TimeValue(time)); } -Variable &Record::addArray(const CString &, ArrayValue *array) +Variable &Record::addArray(const String &name, ArrayValue *array) { // Automatically create an empty array if one is not provided. if (!array) array = new ArrayValue; return add(name, Variable::AllowArray).set(array); } -Variable &Record::addDictionary(const CString &) +Variable &Record::addDictionary(const String &name) { return add(name, Variable::AllowDictionary).set(new DictionaryValue); } -Variable &Record::addBlock(const CString &) +Variable &Record::addBlock(const String &name) { return add(name, Variable::AllowBlock).set(new BlockValue); } @@ -614,14 +614,14 @@ Variable &Record::addFunction(const String &name, Function *func) return add(name, Variable::AllowFunction).set(new FunctionValue(func)); } -Record &Record::add(const CString &, Record *subrecord) +Record &Record::add(const String &name, Record *subrecord) { std::unique_ptr sub(subrecord); add(name).set(RecordValue::takeRecord(sub.release())); return *subrecord; } -Record &Record::addSubrecord(const CString &, SubrecordAdditionBehavior behavior) +Record &Record::addSubrecord(const String &name, SubrecordAdditionBehavior behavior) { if (behavior == KeepExisting) { @@ -637,19 +637,19 @@ Record &Record::addSubrecord(const CString &, SubrecordAdditionBehavior behavior return add(name, new Record); } -Record *Record::removeSubrecord(const CString &) +Record *Record::removeSubrecord(const String &name) { - Members::const_iterator found = d->members.find(name); - if (found != d->members.end() && d->isSubrecord(*found.value())) + auto found = d->members.find(String(name)); + if (found != d->members.end() && d->isSubrecord(*found->second)) { - Record *returnedToCaller = found.value()->value().takeRecord(); - remove(*found.value()); + Record *returnedToCaller = found->second->value().takeRecord(); + remove(*found->second); return returnedToCaller; } throw NotFoundError("Record::remove", "Subrecord '" + name + "' not found"); } -Variable &Record::set(const CString &, bool value) +Variable &Record::set(const String &name, bool value) { DE_GUARD(d); @@ -660,7 +660,7 @@ Variable &Record::set(const CString &, bool value) return addBoolean(name, value); } -Variable &Record::set(const CString &, char const *value) +Variable &Record::set(const String &name, char const *value) { DE_GUARD(d); @@ -671,7 +671,7 @@ Variable &Record::set(const CString &, char const *value) return addText(name, value); } -Variable &Record::set(const CString &, Value::Text const &value) +Variable &Record::set(const String &name, Value::Text const &value) { DE_GUARD(d); @@ -682,7 +682,7 @@ Variable &Record::set(const CString &, Value::Text const &value) return addText(name, value); } -Variable &Record::set(const CString &name, Value::Number value) +Variable &Record::set(const String &name, Value::Number value) { return set(name, NumberValue(value)); } @@ -698,32 +698,32 @@ Variable &Record::set(const String &name, const NumberValue &value) return add(name, Variable::AllowNumber).set(value); } -Variable &Record::set(const CString &, dint32 value) +Variable &Record::set(const String &name, dint32 value) { return set(name, NumberValue(value)); } -Variable &Record::set(const CString &, duint32 value) +Variable &Record::set(const String &name, duint32 value) { return set(name, NumberValue(value)); } -Variable &Record::set(const CString &, dint64 value) +Variable &Record::set(const String &name, dint64 value) { return set(name, NumberValue(value)); } -Variable &Record::set(const CString &, duint64 value) +Variable &Record::set(const String &name, duint64 value) { return set(name, NumberValue(value)); } -Variable &Record::set(const CString &, unsigned long value) +Variable &Record::set(const String &name, unsigned long value) { return set(name, NumberValue(value)); } -Variable &Record::set(const CString &, Time const &value) +Variable &Record::set(const String &name, Time const &value) { DE_GUARD(d); @@ -734,7 +734,7 @@ Variable &Record::set(const CString &, Time const &value) return addTime(name, value); } -Variable &Record::set(const CString &, Block const &value) +Variable &Record::set(const String &name, Block const &value) { DE_GUARD(d); @@ -746,6 +746,7 @@ Variable &Record::set(const CString &, Block const &value) var.value().block() = value; return var; } +Variable &Record::set(const String &name, ArrayValue *value) Variable &Record::set(const CString &name, const Record &value) { @@ -772,7 +773,7 @@ Variable &Record::set(const CString &name, ArrayValue *value) return addArray(name, value); } -Variable &Record::set(const CString &name, Value *value) +Variable &Record::set(const String &name, Value *value) { DENG2_GUARD(d); @@ -794,7 +795,7 @@ Variable &Record::set(const CString &name, const Value &value) return add(name).set(value); } -Variable &Record::appendWord(String const &name, String const &word, String const &separator) +Variable &Record::appendWord(const String &name, const String &word, const String &separator) { DE_GUARD(d); @@ -804,7 +805,7 @@ Variable &Record::appendWord(String const &name, String const &word, String cons return (*this)[name]; } -Variable &Record::appendUniqueWord(const CString &, const CString &word, const CString &separator) +Variable &Record::appendUniqueWord(const String &name, const String &word, const String &separator) { DE_GUARD(d); @@ -816,16 +817,19 @@ Variable &Record::appendUniqueWord(const CString &, const CString &word, const C return (*this)[name]; } -Variable &Record::appendMultipleUniqueWords(const CString &, const CString &words, const CString &separator) +Variable &Record::appendMultipleUniqueWords(const String &name, const String &words, const String &separator) +{ + for (const String &word : words.split(separator)) { - foreach (String word, words.split(separator, QString::SkipEmptyParts)) + if (!word.empty()) { appendUniqueWord(name, word, separator); } + } return (*this)[name]; } -Variable &Record::appendToArray(const CString &, Value *value) +Variable &Record::appendToArray(const String &name, Value *value) { DE_GUARD(d); @@ -840,7 +844,7 @@ Variable &Record::appendToArray(const CString &, Value *value) return var; } -Variable &Record::insertToSortedArray(const CString &, Value *value) +Variable &Record::insertToSortedArray(const String &name, Value *value) { DE_GUARD(d); @@ -865,12 +869,12 @@ Variable &Record::insertToSortedArray(const CString &, Value *value) return var; } -Variable &Record::operator [] (const CString &name) +Variable &Record::operator [] (const String &name) { return const_cast((*const_cast(this))[name]); } -Variable const &Record::operator [] (const CString &name) const +Variable const &Record::operator [] (const String &name) const { // Path notation allows looking into subrecords. Variable const *found = d->findMemberByPath(name); @@ -881,36 +885,35 @@ Variable const &Record::operator [] (const CString &name) const throw NotFoundError("Record::operator []", "Variable '" + name + "' not found"); } -Variable *Record::tryFind(const CString &name) +Variable *Record::tryFind(const String &name) { return const_cast(d->findMemberByPath(name)); } -Variable const *Record::tryFind(const CString &name) const +Variable const *Record::tryFind(const String &name) const { return d->findMemberByPath(name); } -Record &Record::subrecord(const CString &) +Record &Record::subrecord(const String &name) { return const_cast((const_cast(this))->subrecord(name)); } -Record const &Record::subrecord(const CString &) const +Record const &Record::subrecord(const String &name) const { // Path notation allows looking into subrecords. - int pos = name.indexOf('.'); - if (pos >= 0) + if (auto pos = name.indexOf('.')) { - return subrecord(name.substr(0, pos)).subrecord(name.substr(pos + 1)); + return subrecord(name.left(pos)).subrecord(name.substr(pos + 1)); } Members::const_iterator found = d->members.find(name); - if (found != d->members.end() && d->isSubrecord(*found.value())) + if (found != d->members.end() && d->isSubrecord(*found->second)) { - return *found.value()->value().record(); + return *found->second->value().record(); } - throw NotFoundError("Record::subrecord", "Subrecord '" + name + "' not found"); + throw NotFoundError("Record::subrecord", stringf("Subrecord '%s' not found", name.c_str())); } dsize Record::size() const @@ -925,9 +928,9 @@ Record::Members const &Record::members() const LoopResult Record::forMembers(std::function func) { - for (Members::iterator i = d->members.begin(); i != d->members.end(); ++i) + for (auto i = d->members.begin(); i != d->members.end(); ++i) { - if (auto result = func(i.key(), *i.value())) + if (auto result = func(i->first, *i->second)) { return result; } @@ -937,9 +940,9 @@ LoopResult Record::forMembers(std::function func) const { - for (Members::const_iterator i = d->members.constBegin(); i != d->members.constEnd(); ++i) + for (Members::const_iterator i = d->members.begin(); i != d->members.end(); ++i) { - if (auto result = func(i.key(), *i.value())) + if (auto result = func(i->first, *i->second)) { return result; } @@ -967,7 +970,7 @@ LoopResult Record::forSubrecords(std::function func) const { - return d->forSubrecords([func] (const CString &, Record &rec) + return d->forSubrecords([func] (const String &name, Record &rec) { return func(name, rec); }); @@ -980,7 +983,7 @@ bool Record::anyMembersChanged() const auto const *const_d = d.getConst(); for (auto i = const_d->members.begin(); i != const_d->members.end(); ++i) { - if (i.value()->flags() & Variable::ValueHasChanged) + if (i->second->flags() & Variable::ValueHasChanged) { return true; } @@ -1002,11 +1005,11 @@ void Record::markAllMembersUnchanged() for (auto i = d->members.begin(); i != d->members.end(); ++i) { - i.value()->setFlags(Variable::ValueHasChanged, UnsetFlags); + i->second->setFlags(Variable::ValueHasChanged, UnsetFlags); - if (d->isSubrecord(*i.value())) + if (d->isSubrecord(*i->second)) { - i.value()->valueAsRecord().markAllMembersUnchanged(); + i->second->valueAsRecord().markAllMembersUnchanged(); } } } @@ -1029,24 +1032,23 @@ String Record::asText(String const &prefix, List *lines) const // Collect lines from this record. for (Members::const_iterator i = d->members.begin(); i != d->members.end(); ++i) { - String separator = (d->isSubrecord(*i.value())? "." : ":"); - String subContent = i.value()->value().asText(); + const char *separator = d->isSubrecord(*i->second)? "." : ":"; + String subContent = i->second->value().asText(); // If the content is very long, shorten it. - int numberOfLines = subContent.count(QChar('\n')); + int numberOfLines = subContent.count('\n'); if (numberOfLines > SUBRECORD_CONTENT_EXCERPT_THRESHOLD) { - subContent = QString("(%1 lines)").arg(numberOfLines); + subContent = String("(%i lines)", numberOfLines); } - KeyValue kv(prefix + i.key() + separator, subContent); + KeyValue kv(prefix + i->first + separator, subContent); lines->push_back(kv); } return ""; } // Top level of the recursion. - std::ostringstream os; List allLines; Vec2ui maxLength; @@ -1060,33 +1062,34 @@ String Record::asText(String const &prefix, List *lines) const maxLength = maxLength.max(Vec2ui(i->first.size(), i->second.size())); } - os.setFieldAlignment(QTextStream::AlignLeft); + std::ostringstream os; + os << std::left << std::setfill(' '); // Print aligned. for (List::iterator i = allLines.begin(); i != allLines.end(); ++i) { int extra = 0; if (i != allLines.begin()) os << "\n"; - os << qSetFieldWidth(maxLength.x) << i->first << qSetFieldWidth(0); + os << std::setw(maxLength.x) << i->first; // Print the value line by line. - int pos = 0; - while (pos >= 0) + String::BytePos pos{0}; + while (pos) { - int next = i->second.indexOf('\n', pos); + auto next = i->second.indexOf("\n", pos); if (pos > 0) { - os << qSetFieldWidth(maxLength.x + extra) << "" << qSetFieldWidth(0); + os << std::setw(maxLength.x + extra) << ""; } - os << i->second.substr(pos, next != String::npos? next - pos + 1 : next); + os << i->second.substr(pos, (next ? (next - pos + 1) : next).index); pos = next; - if (pos != String::npos) pos++; + if (pos) pos++; } } - return result; + return os.str(); } -Function const &Record::function(const CString &) const +Function const &Record::function(const String &name) const { return (*this)[name].value().function(); } @@ -1112,9 +1115,9 @@ void Record::operator >> (Writer &to) const DE_GUARD(d); to << d->uniqueId << duint32(d->members.size()); - DE_FOR_EACH_CONST(Members, i, d->members) + for (const auto &i : d->members) { - to << *i.value(); + to << *i.second; } } @@ -1154,7 +1157,7 @@ void Record::operator << (Reader &from) #ifdef DE_DEBUG DE_FOR_EACH(Members, i, d->members) { - DE_ASSERT(i.value()->audienceForDeletion().contains(d)); + DE_ASSERT(i->second->audienceForDeletion().contains(d)); } #endif } @@ -1165,7 +1168,7 @@ Record &Record::operator << (NativeFunctionSpec const &spec) return *this; } -Record const &Record::parentRecordForMember(const CString &) const +Record const &Record::parentRecordForMember(const String &name) const { String const lastOmitted = name.fileNamePath('.'); if (lastOmitted.isEmpty()) return *this; @@ -1177,14 +1180,14 @@ Record const &Record::parentRecordForMember(const CString &) const String Record::asInfo() const { String out; - QTextStream os(&out); - os.setCodec("UTF-8"); - for (auto i = d->members.constBegin(); i != d->members.constEnd(); ++i) + for (const auto &i : d->members) { - if (out) os << "\n"; + if (out) out += "\n"; + + Variable const &var = *i.second; const Variable &var = *i.value(); - String src = i.key(); + String src = i.first; if (is(var.value())) { @@ -1207,13 +1210,12 @@ String Record::asInfo() const { src += ": " + valueText; } - } - os << src; + } } return out; } -std::ostream &operator << (std::ostream &os, Record const &record) +std::ostream &operator<<(std::ostream &os, Record const &record) { return os << record.asText(); } diff --git a/doomsday/libs/core/src/data/recordaccessor.cpp b/doomsday/libs/core/src/data/recordaccessor.cpp index 47b4c9007c..ba79ffd65c 100644 --- a/doomsday/libs/core/src/data/recordaccessor.cpp +++ b/doomsday/libs/core/src/data/recordaccessor.cpp @@ -39,104 +39,104 @@ Record const *RecordAccessor::accessedRecordPtr() const return _rec; } -bool RecordAccessor::has(const char *name) const +bool RecordAccessor::has(const String &name) const { return accessedRecord().has(name); } -Value const &RecordAccessor::get(const char *name) const +Value const &RecordAccessor::get(const String &name) const { return accessedRecord()[name].value(); } -dint RecordAccessor::geti(const char *name) const +dint RecordAccessor::geti(const String &name) const { return get(name).asInt(); } -dint RecordAccessor::geti(const char *name, dint defaultValue) const +dint RecordAccessor::geti(const String &name, dint defaultValue) const { if (!accessedRecord().hasMember(name)) return defaultValue; return geti(name); } -bool RecordAccessor::getb(const char *name) const +bool RecordAccessor::getb(const String &name) const { return get(name).isTrue(); } -bool RecordAccessor::getb(const char *name, bool defaultValue) const +bool RecordAccessor::getb(const String &name, bool defaultValue) const { if (!accessedRecord().hasMember(name)) return defaultValue; return getb(name); } -duint RecordAccessor::getui(const char *name) const +duint RecordAccessor::getui(const String &name) const { return duint(get(name).asNumber()); } -duint RecordAccessor::getui(const char *name, duint defaultValue) const +duint RecordAccessor::getui(const String &name, duint defaultValue) const { if (!accessedRecord().hasMember(name)) return defaultValue; return getui(name); } -dfloat RecordAccessor::getf(const char *name) const +dfloat RecordAccessor::getf(const de::String &name) const { return dfloat(getd(name)); } -dfloat RecordAccessor::getf(const char *name, dfloat defaultValue) const +dfloat RecordAccessor::getf(const String &name, dfloat defaultValue) const { if (!accessedRecord().hasMember(name)) return defaultValue; return getf(name); } -ddouble RecordAccessor::getd(const char *name) const +ddouble RecordAccessor::getd(const String &name) const { return get(name).asNumber(); } -ddouble RecordAccessor::getd(const char *name, ddouble defaultValue) const +ddouble RecordAccessor::getd(const String &name, ddouble defaultValue) const { if (!accessedRecord().hasMember(name)) return defaultValue; return getd(name); } -String RecordAccessor::gets(const char *name) const +String RecordAccessor::gets(const String &name) const { return get(name).asText(); } -String RecordAccessor::gets(const char *name, String const &defaultValue) const +String RecordAccessor::gets(const String &name, const char *defaultValue) const { if (!accessedRecord().hasMember(name)) return defaultValue; return gets(name); } -ArrayValue const &RecordAccessor::geta(const char *name) const +ArrayValue const &RecordAccessor::geta(const String &name) const { return getAs(name); } -DictionaryValue const &RecordAccessor::getdt(const char *name) const +DictionaryValue const &RecordAccessor::getdt(const String &name) const { return getAs(name); } -RecordValue const &RecordAccessor::getr(const char *name) const +RecordValue const &RecordAccessor::getr(const String &name) const { return getAs(name); } -StringList RecordAccessor::getStringList(const char *name, StringList defaultValue) const +StringList RecordAccessor::getStringList(const String &name, StringList defaultValue) const { if (!accessedRecord().has(name)) return defaultValue; return get(name).asStringList(); } -Record const &RecordAccessor::subrecord(const char *name) const +Record const &RecordAccessor::subrecord(const String &name) const { return accessedRecord().subrecord(name); } diff --git a/doomsday/libs/core/src/data/recordvalue.cpp b/doomsday/libs/core/src/data/recordvalue.cpp index ea903fe9c0..36e176ad80 100644 --- a/doomsday/libs/core/src/data/recordvalue.cpp +++ b/doomsday/libs/core/src/data/recordvalue.cpp @@ -182,7 +182,7 @@ Record const &RecordValue::dereference() const Value::Text RecordValue::typeId() const { - return QStringLiteral("Record"); + static String id("Record"); return id; } Value *RecordValue::duplicate() const @@ -282,7 +282,7 @@ void RecordValue::call(Process &process, Value const &arguments, Value *) const // Calling a record causes it to be treated as a class and a new record is // initialized as a member of the class. - QScopedPointer instance(new RecordValue(new Record, RecordValue::OwnsRecord)); + std::unique_ptr instance(RecordValue::takeRecord(new Record)); instance->record()->addSuperRecord(*d->record); @@ -296,7 +296,7 @@ void RecordValue::call(Process &process, Value const &arguments, Value *) const delete process.context().evaluator().popResult(); } - process.context().evaluator().pushResult(instance.take()); + process.context().evaluator().pushResult(instance.release()); } // Flags for serialization: diff --git a/doomsday/libs/core/src/data/sourcelinetable.cpp b/doomsday/libs/core/src/data/sourcelinetable.cpp index 7a4a1ece81..00f976f332 100644 --- a/doomsday/libs/core/src/data/sourcelinetable.cpp +++ b/doomsday/libs/core/src/data/sourcelinetable.cpp @@ -65,7 +65,7 @@ SourceLineTable::LineId SourceLineTable::lineId(String const &path, duint lineNu String SourceLineTable::sourceLocation(LineId sourceId) const { auto const location = sourcePathAndLineNumber(sourceId); - return QString("%1:%2").arg(location.first).arg(location.second); + return String::format("%s:%u", location.first.c_str(), location.second); } SourceLineTable::PathAndLine SourceLineTable::sourcePathAndLineNumber(LineId sourceId) const @@ -74,10 +74,10 @@ SourceLineTable::PathAndLine SourceLineTable::sourcePathAndLineNumber(LineId sou DE_GUARD(d); - auto found = d->lookup.constFind(sourceId >> SOURCE_SHIFT); - if (found != d->lookup.constEnd()) + auto found = d->lookup.find(sourceId >> SOURCE_SHIFT); + if (found != d->lookup.end()) { - return PathAndLine(found.value()->path().toStringRef(), lineNumber); + return PathAndLine(found->second->path(), lineNumber); } return PathAndLine("", lineNumber); } diff --git a/doomsday/libs/core/src/data/string.cpp b/doomsday/libs/core/src/data/string.cpp index cf5bc0c790..22dee68588 100644 --- a/doomsday/libs/core/src/data/string.cpp +++ b/doomsday/libs/core/src/data/string.cpp @@ -159,11 +159,26 @@ std::wstring String::toWideString() const return ws; } +CString String::toCString() const +{ + return {begin(), end()}; +} + bool String::contains(const char *cStr) const { return indexOfCStr_String(&_str, cStr) != iInvalidPos; } +int String::count(char ch) const +{ + int num = 0; + for (const char *i = constBegin_String(&_str), *end = constEnd_String(&_str); i != end; ++i) + { + if (*i == ch) ++num; + } + return num; +} + String String::substr(CharPos pos, dsize count) const { iString *sub = mid_String(&_str, pos.index, count); @@ -268,6 +283,14 @@ void String::insert(BytePos pos, const String &str) insertData_Block(&_str.chars, pos.index, str.data(), str.size()); } +String &String::replace(Char before, Char after) +{ + iMultibyteChar mb1, mb2; + init_MultibyteChar(&mb1, before); + init_MultibyteChar(&mb2, after); + return replace(mb1.bytes, mb2.bytes); +} + String &String::replace(const CString &before, const CString &after) { const String oldTerm{before}; @@ -301,6 +324,11 @@ String String::operator/(const String &path) const return concatenatePath(path); } +String String::operator/(const CString &path) const +{ + return concatenatePath(String(path)); +} + String String::operator%(const PatternArgs &args) const { String result; @@ -438,7 +466,7 @@ String String::upperFirstChar() const { if (isEmpty()) return ""; const_iterator i = begin(); - String capitalized(1, towupper(*i++)); + String capitalized(1, Char(towupper(*i++))); appendCStr_String(&capitalized._str, i); return capitalized; } diff --git a/doomsday/libs/core/src/data/stringpool.cpp b/doomsday/libs/core/src/data/stringpool.cpp index aaca7730d7..b596380d75 100644 --- a/doomsday/libs/core/src/data/stringpool.cpp +++ b/doomsday/libs/core/src/data/stringpool.cpp @@ -53,15 +53,15 @@ class CaselessString : public ISerializable : _str(), _id(0), _userValue(0), _userPointer(0) {} - CaselessString(QString text) + CaselessString(const String &text) : _str(text), _id(0), _userValue(0), _userPointer(0) {} CaselessString(CaselessString const &other) - : ISerializable(), _str(other._str), _id(other._id), _userValue(other._userValue), _userPointer(0) + : _str(other._str), _id(other._id), _userValue(other._userValue), _userPointer(0) {} - void setText(String &text) + void setText(const String &text) { _str = text; } @@ -72,10 +72,10 @@ class CaselessString : public ISerializable return _str; } bool operator < (CaselessString const &other) const { - return _str.compare(other, Qt::CaseInsensitive) < 0; + return _str.compare(other, String::CaseInsensitive) < 0; } bool operator == (CaselessString const &other) const { - return !_str.compare(other, Qt::CaseInsensitive); + return _str.compare(other, String::CaseInsensitive) == 0; } InternalId id() const { return _id; @@ -174,7 +174,7 @@ DE_PIMPL_NOREF(StringPool), public Lockable void clear() { DE_GUARD(this); - + for (dsize i = 0; i < idMap.size(); ++i) { if (!idMap[i]) continue; // Unused slot. @@ -194,13 +194,13 @@ DE_PIMPL_NOREF(StringPool), public Lockable DE_ASSERT(count == idMap.size() - available.size()); } - Interns::iterator findIntern(String text) + Interns::iterator findIntern(const String &text) { CaselessString const key(text); return interns.find(CaselessStringRef(&key)); // O(log n) } - Interns::const_iterator findIntern(String text) const + Interns::const_iterator findIntern(const String &text) const { CaselessString const key(text); return interns.find(CaselessStringRef(&key)); // O(log n) @@ -213,7 +213,7 @@ DE_PIMPL_NOREF(StringPool), public Lockable * @param text Text string to add to the interned strings. A copy is * made of this. */ - InternalId copyAndAssignUniqueId(String const &text) + InternalId copyAndAssignUniqueId(const String &text) { CaselessString *str = new CaselessString(text); @@ -299,7 +299,7 @@ void StringPool::clear() bool StringPool::empty() const { DE_GUARD(d); - + d->assertCount(); return !d->count; } @@ -312,10 +312,10 @@ dsize StringPool::size() const return d->count; } -StringPool::Id StringPool::intern(String str) +StringPool::Id StringPool::intern(const String &str) { DE_GUARD(d); - + Interns::iterator found = d->findIntern(str); // O(log n) if (found != d->interns.end()) { @@ -325,10 +325,10 @@ StringPool::Id StringPool::intern(String str) return EXPORT_ID(d->copyAndAssignUniqueId(str)); // O(log n) } -String StringPool::internAndRetrieve(String str) +String StringPool::internAndRetrieve(const String &str) { DE_GUARD(d); - + InternalId id = IMPORT_ID(intern(str)); return *d->idMap[id]; } @@ -405,7 +405,7 @@ StringPool::Id StringPool::isInterned(String str) const String StringPool::string(Id id) const { DE_GUARD(d); - + /// @throws InvalidIdError Provided identifier is not in use. return stringRef(id); } @@ -427,7 +427,7 @@ String const &StringPool::stringRef(StringPool::Id id) const return *d->idMap[internalId]; } -bool StringPool::remove(String str) +bool StringPool::remove(const String &str) { DE_GUARD(d); @@ -472,7 +472,7 @@ LoopResult StringPool::forAll(std::function func) const } // Implements ISerializable. -void StringPool::operator >> (Writer &to) const +void StringPool::operator>>(Writer &to) const { DE_GUARD(d); @@ -487,7 +487,7 @@ void StringPool::operator >> (Writer &to) const } } -void StringPool::operator << (Reader &from) +void StringPool::operator<<(Reader &from) { DE_GUARD(d); diff --git a/doomsday/libs/core/src/data/value.cpp b/doomsday/libs/core/src/data/value.cpp index c2be0044f4..ed3b832e44 100644 --- a/doomsday/libs/core/src/data/value.cpp +++ b/doomsday/libs/core/src/data/value.cpp @@ -101,10 +101,9 @@ dsize Value::size() const Value const &Value::element(Value const &/*index*/) const { /// @throw IllegalError Value cannot be indexed. - throw IllegalError("Value::element", - String("Value cannot be indexed (%1 \"%2\")") - .arg(typeid(*this).name()) - .arg(asText())); + throw IllegalError( + "Value::element", + stringf("Value cannot be indexed (%s \"%s\")", typeid(*this).name(), asText().c_str())); } Value &Value::element(Value const &/*index*/) @@ -265,7 +264,8 @@ Value *Value::constructFrom(Reader &reader) return result.release(); } -Value *Value::constructFrom(QVariant const &variant) +/* +Value *Value::constructFrom(Value const &value) { switch (variant.type()) { @@ -320,6 +320,7 @@ Value *Value::constructFrom(QVariant const &variant) return new TextValue(variant.toString()); } +*/ Value const &Value::element(dint index) const { diff --git a/doomsday/libs/core/src/data/variable.cpp b/doomsday/libs/core/src/data/variable.cpp index bb41bdc344..cadd04f93e 100644 --- a/doomsday/libs/core/src/data/variable.cpp +++ b/doomsday/libs/core/src/data/variable.cpp @@ -66,7 +66,7 @@ DE_AUDIENCE_METHOD(Variable, Deletion) DE_AUDIENCE_METHOD(Variable, Change) DE_AUDIENCE_METHOD(Variable, ChangeFrom) -Variable::Variable(const CString &name, Value *initial, Flags const &m) +Variable::Variable(const String &name, Value *initial, Flags const &m) : d(new Impl) { d->name = name; diff --git a/doomsday/libs/core/src/filesys/fileindex.cpp b/doomsday/libs/core/src/filesys/fileindex.cpp index b08decbe21..ba9b3585a7 100644 --- a/doomsday/libs/core/src/filesys/fileindex.cpp +++ b/doomsday/libs/core/src/filesys/fileindex.cpp @@ -161,7 +161,7 @@ static bool fileNotInAnyLoadedPackage(File *file) return !App::packageLoader().isLoaded(identifier); } -void FileIndex::findPartialPath(const CString &path, FoundFiles &found, Behavior behavior) const +void FileIndex::findPartialPath(const String &path, FoundFiles &found, Behavior behavior) const { d->findPartialPath(path, found); @@ -171,7 +171,7 @@ void FileIndex::findPartialPath(const CString &path, FoundFiles &found, Behavior } } -void FileIndex::findPartialPath(Folder const &rootFolder, const CString &path, +void FileIndex::findPartialPath(Folder const &rootFolder, const String &path, FoundFiles &found, Behavior behavior) const { findPartialPath(path, found, behavior); @@ -182,7 +182,7 @@ void FileIndex::findPartialPath(Folder const &rootFolder, const CString &path, }); } -void FileIndex::findPartialPath(const CString &packageId, const CString &path, +void FileIndex::findPartialPath(const String &packageId, const String &path, FoundFiles &found) const { // We can only look in Folder-like packages. @@ -198,7 +198,7 @@ void FileIndex::findPartialPath(const CString &packageId, const CString &path, } } -int FileIndex::findPartialPathInPackageOrder(const CString &path, FoundFiles &found, Behavior behavior) const +int FileIndex::findPartialPathInPackageOrder(const String &path, FoundFiles &found, Behavior behavior) const { findPartialPath(path, found, behavior); App::packageLoader().sortInPackageOrder(found);