summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/llinitparam.h14
-rw-r--r--indra/llcommon/llkeybind.cpp4
-rw-r--r--indra/llcommon/llkeybind.h4
-rw-r--r--indra/llcommon/llsd.cpp25
-rw-r--r--indra/llcommon/llsd.h1
-rw-r--r--indra/llcommon/llstring.cpp23
-rw-r--r--indra/llcommon/llstring.h63
-rw-r--r--indra/llcommon/llthreadsafequeue.h5
8 files changed, 123 insertions, 16 deletions
diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h
index 32d7b17034..170a171502 100644
--- a/indra/llcommon/llinitparam.h
+++ b/indra/llcommon/llinitparam.h
@@ -1771,8 +1771,13 @@ namespace LLInitParam
// implicit conversion
operator const container_t&() const { return mValues; }
+ operator container_t&() { return mValues; }
// explicit conversion
const container_t& operator()() const { return mValues; }
+ container_t& operator()() { return mValues; }
+ // direct Nth item access
+ const typename NAME_VALUE_LOOKUP::type_value_t& operator()(size_t index) const { return mValues[index]; }
+ typename NAME_VALUE_LOOKUP::type_value_t& operator()(size_t index) { return mValues[index]; }
iterator begin() { return mValues.begin(); }
iterator end() { return mValues.end(); }
@@ -2102,13 +2107,13 @@ namespace LLInitParam
class Multiple : public TypedParam<T, NAME_VALUE_LOOKUP, true>
{
typedef TypedParam<T, NAME_VALUE_LOOKUP, true> super_t;
- typedef Multiple<T, RANGE, NAME_VALUE_LOOKUP> self_t;
- typedef typename super_t::container_t container_t;
+ typedef Multiple<T, RANGE, NAME_VALUE_LOOKUP> self_t;
+ typedef typename super_t::container_t container_t;
typedef typename super_t::value_t value_t;
public:
- typedef typename super_t::iterator iterator;
- typedef typename super_t::const_iterator const_iterator;
+ typedef typename super_t::iterator iterator;
+ typedef typename super_t::const_iterator const_iterator;
using super_t::operator();
using super_t::operator const container_t&;
@@ -2836,3 +2841,4 @@ namespace LLInitParam
#endif // LL_LLPARAM_H
+
diff --git a/indra/llcommon/llkeybind.cpp b/indra/llcommon/llkeybind.cpp
index 34254f3ef5..73a207504e 100644
--- a/indra/llcommon/llkeybind.cpp
+++ b/indra/llcommon/llkeybind.cpp
@@ -175,7 +175,7 @@ LLKeyBind::LLKeyBind(const LLSD &key_bind)
}
}
-bool LLKeyBind::operator==(const LLKeyBind& rhs)
+bool LLKeyBind::operator==(const LLKeyBind& rhs) const
{
auto size = mData.size();
if (size != rhs.mData.size()) return false;
@@ -188,7 +188,7 @@ bool LLKeyBind::operator==(const LLKeyBind& rhs)
return true;
}
-bool LLKeyBind::operator!=(const LLKeyBind& rhs)
+bool LLKeyBind::operator!=(const LLKeyBind& rhs) const
{
auto size = mData.size();
if (size != rhs.mData.size()) return true;
diff --git a/indra/llcommon/llkeybind.h b/indra/llcommon/llkeybind.h
index 68efe38689..eb9b68f9d1 100644
--- a/indra/llcommon/llkeybind.h
+++ b/indra/llcommon/llkeybind.h
@@ -64,8 +64,8 @@ public:
LLKeyBind() {}
LLKeyBind(const LLSD &key_bind);
- bool operator==(const LLKeyBind& rhs);
- bool operator!=(const LLKeyBind& rhs);
+ bool operator==(const LLKeyBind& rhs) const;
+ bool operator!=(const LLKeyBind& rhs) const;
bool isEmpty() const;
bool empty() const { return isEmpty(); };
diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp
index 77fe545c3f..1058ab385b 100644
--- a/indra/llcommon/llsd.cpp
+++ b/indra/llcommon/llsd.cpp
@@ -974,6 +974,31 @@ void LLSD::clear() { Impl::assignUndefined(impl); }
LLSD::Type LLSD::type() const { return safe(impl).type(); }
+bool LLSD::isEmpty() const
+{
+ switch (type())
+ {
+ case TypeUndefined:
+ return true; // Always empty
+ case TypeBinary:
+ return !asBoolean(); // Empty when default
+ case TypeInteger:
+ return !asInteger(); // Empty when default
+ case TypeReal:
+ return !asReal(); // Empty when default
+ case TypeString:
+ case TypeURI:
+ return asString().empty(); // Empty natively
+ case TypeArray:
+ case TypeMap:
+ return !size(); // Empty natively
+ default:;
+ }
+ // All other value types (TypeDate) don't have default values so can't be empty
+ return false;
+}
+
+
// Scalar Constructors
LLSD::LLSD(Boolean v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(Integer v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h
index d2b3548831..e018b400cb 100644
--- a/indra/llcommon/llsd.h
+++ b/indra/llcommon/llsd.h
@@ -420,6 +420,7 @@ public:
bool isBinary() const { return type() == TypeBinary; }
bool isMap() const { return type() == TypeMap; }
bool isArray() const { return type() == TypeArray; }
+ bool isEmpty() const;
//@}
/** @name Automatic Cast Protection
diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index 447fa2d9dd..e38622b43b 100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -1144,18 +1144,27 @@ void LLStringOps::setupDayFormat(const std::string& data)
}
-std::string LLStringOps::getDatetimeCode (std::string key)
+std::string LLStringOps::getDatetimeCode(std::string key)
{
- std::map<std::string, std::string>::iterator iter;
+ std::map<std::string, std::string>::iterator iter = datetimeToCodes.find(key);
+ return iter == datetimeToCodes.end() ? LLStringUtil::null : iter->second;
+}
- iter = datetimeToCodes.find (key);
- if (iter != datetimeToCodes.end())
+void LLStringOps::splitString(const std::string& text, char delimiter,
+ std::function<void(const std::string&)> handler)
+{
+ std::size_t from = 0;
+ for (std::size_t i = 0; i < text.size(); ++i)
{
- return iter->second;
+ if (text[i] == delimiter)
+ {
+ handler(text.substr(from, i - from));
+ from = i + 1;
+ }
}
- else
+ if (from <= text.size())
{
- return std::string("");
+ handler(text.substr(from));
}
}
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index d65fb16f5b..b15a85cb2a 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -36,6 +36,7 @@
//#include <locale>
#include <iomanip>
#include <algorithm>
+#include <functional>
#include <vector>
#include <map>
#include <type_traits>
@@ -214,6 +215,9 @@ public:
static std::string getDatetimeCode (std::string key);
+ static void splitString(const std::string& text, char delimiter,
+ std::function<void(const std::string&)> handler);
+
// Express a value like 1234567 as "1.23M"
static std::string getReadableNumber(F64 num);
};
@@ -443,6 +447,65 @@ public:
static bool isPartOfWord(T c) { return (c == (T)'_') || LLStringOps::isAlnum(c); }
+ // Join non-empty strings from values using value itself and delimiter
+ template<class C>
+ static std::string join(const C& values, T delimiter = ',')
+ {
+ std::string result;
+ for (const std::string& value : values)
+ {
+ if (!value.empty())
+ {
+ if (!result.empty())
+ {
+ result += delimiter;
+ }
+ result += value;
+ }
+ }
+ return result;
+ }
+
+ // Join non-empty strings from values using stringify(value) and delimiter
+ template<class C, class V>
+ static std::string join(const C& values, std::function<std::string(const V&)> stringify, T delimiter = ',')
+ {
+ std::string result;
+ for (const V& value : values)
+ {
+ std::string string = stringify(value);
+ if (!string.empty())
+ {
+ if (!result.empty())
+ {
+ result += delimiter;
+ }
+ result += string;
+ }
+ }
+ return result;
+ }
+
+ // Join non-empty strings from values using stringify(index, value) and delimiter
+ template<class C, class V>
+ static std::string join(const C& values, std::function<std::string(size_t index, const V&)> stringify, T delimiter = ',')
+ {
+ std::string result;
+ for (size_t i = 0; i < values.size(); ++i)
+ {
+ std::string string = stringify(i, values[i]);
+ if (!string.empty())
+ {
+ if (!result.empty())
+ {
+ result += delimiter;
+ }
+ result += string;
+ }
+ }
+ return result;
+ }
+
#ifdef _DEBUG
LL_COMMON_API static void testHarness();
#endif
diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h
index 034e3f7897..7a5eb5b33d 100644
--- a/indra/llcommon/llthreadsafequeue.h
+++ b/indra/llcommon/llthreadsafequeue.h
@@ -452,7 +452,10 @@ ElementT LLThreadSafeQueue<ElementT, QueueT>::pop(void)
// so we can finish draining the queue.
pop_result popped = pop_(lock1, value);
if (popped == POPPED)
- return std::move(value);
+ // don't use std::move when returning local value because
+ // it prevents the compiler from optimizing with copy elision
+ //return std::move(value);
+ return value;
// Once the queue is DONE, there will never be any more coming.
if (popped == DONE)