#define DALI_TOOLKIT_INTERNAL_BUILDER_DICTIONARY_H
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
#include <dali/public-api/common/vector-wrapper.h>
+
#include <algorithm>
+#include <string_view>
namespace Dali
{
-extern bool CaseInsensitiveStringCompare( const std::string& a, const std::string& b );
+extern bool CaseInsensitiveStringCompare(std::string_view a, std::string_view b);
namespace Toolkit
{
*
* It enables lookup of keys via case-insensitive match.
*/
+
+using DictionaryKeys = std::vector<std::string>;
+
+inline void Merge( DictionaryKeys& toDict, const DictionaryKeys& fromDict )
+{
+ for(const auto& element : fromDict)
+ {
+ auto iter = std::find(toDict.cbegin(), toDict.cend(), element);
+ if(iter == toDict.cend())
+ {
+ toDict.push_back(element);
+ }
+ }
+}
+
+
template<typename EntryType>
class Dictionary
{
{
std::string key;
EntryType entry;
- Element( const std::string&name, EntryType entry )
- : key( name ),
- entry( entry )
+ Element(std::string name, EntryType entry)
+ : key(std::move(name)),
+ entry(std::move(entry))
{
}
};
- typedef std::vector<Element> Elements;
+ using Elements = std::vector<Element>;
Elements container;
+ auto FindElementCaseInsensitive(std::string_view key) const
+ {
+ return std::find_if(
+ Begin(), End(), [key](auto& e) { return Dali::CaseInsensitiveStringCompare(e.key, key); });
+ }
+
+ auto FindElement(std::string_view key)
+ {
+ return std::find_if(container.begin(), container.end(), [key](auto& e){
+ return bool(key == e.key);
+ });
+ }
+
public:
/**
* Only allow const iteration over the dictionary
*/
- typedef typename Elements::const_iterator iterator;
-
+ using iterator = typename Elements::const_iterator;
/**
* Constructor
*/
- Dictionary<EntryType>()
- {
- }
+ Dictionary<EntryType>() = default;
/**
* Add a key value pair to the dictionary.
* If the entry does not already exist, add it to the dictionary
- * using a shallow copy
*/
- bool Add( const std::string& name, const EntryType& entry )
+ bool Add(std::string name, EntryType entry)
{
- for( typename Elements::iterator iter = container.begin(); iter != container.end(); ++iter )
+ auto iter = FindElement(name);
+ if(iter != End())
{
- if( iter->key == name )
- {
- return false;
- }
+ return false;
}
- container.push_back( Element(name, entry) );
+
+ container.push_back(Element(std::move(name), std::move(entry)));
return true;
}
/**
* Add a key-value pair to the dictionary
* If the entry does not already exist, add it to the dictionary
- * (shallow copy)
*/
- bool Add( const char* name, const EntryType& entry )
+ bool Add(const char* name, EntryType entry)
{
- bool result=false;
- if( name != NULL )
+ if(name != nullptr)
{
- std::string theName(name);
- result=Add(theName, entry);
+ return Add(std::string(name), std::move(entry));
}
- return result;
+ return false;
}
/**
- * Find the element in the dictionary pointed at by key, and
- * return a pointer to it, or NULL.
+ * Remove a key value pair from the dictionary.
*/
- EntryType* Find( const std::string& key ) const
+ void Remove(std::string_view name)
{
- EntryType* result=NULL;
-
- if( ! key.empty() )
+ if(!name.empty())
{
- for( typename Elements::iterator iter = container.begin(); iter != container.end(); ++iter )
+ auto iter = FindElement(name);
+
+ if(iter != End())
{
- if( iter->key == key )
- {
- result = &(iter->entry);
- break;
- }
+ container.erase( iter );
}
}
- return result;
}
- /**
- * Find the element in the dictionary pointed at by key, and
- * return a pointer to it, or NULL
- */
- EntryType* Find( const char* key ) const
+ void Merge( const Dictionary<EntryType>& dictionary )
{
- if( key != NULL )
+ for(const auto& element : dictionary.container)
{
- std::string theKey(key);
- return Find(theKey);
+ auto iter = FindElement(element.key);
+
+ if(iter == End())
+ {
+ container.push_back(Element(element.key, element.entry));
+ }
+ else
+ {
+ iter->entry = element.entry;
+ }
}
- return NULL;
}
/**
- * Find the element in the dictionary pointed at by key using a case
+ * Find the element in the dictionary pointed at by key, and
* insensitive search, and return a const pointer to it, or NULL
*/
- const EntryType* FindCaseInsensitiveC( const std::string& key ) const
+ const EntryType* FindConst(std::string_view key) const
{
if( ! key.empty() )
{
- for( typename Elements::const_iterator iter = container.begin(); iter != container.end(); ++iter )
+ auto iter = FindElementCaseInsensitive(key);
+
+ if(iter != End())
{
- if( Dali::CaseInsensitiveStringCompare(iter->key, key ))
- {
- const EntryType* result = &(iter->entry);
- return result;
- }
+ return &(iter->entry);
}
}
- return NULL;
+ return nullptr;
}
/**
* Find the element in the dictionary pointed at by key using a case
* insensitive search, and return a non-const pointer to it, or NULL
*/
- EntryType* FindCaseInsensitive( const std::string& key ) const
+ EntryType* Find(std::string_view key) const
{
- EntryType* result = NULL;
if( ! key.empty() )
{
- for( typename Elements::const_iterator iter = container.begin(); iter != container.end(); ++iter )
+ auto iter = FindElementCaseInsensitive(key);
+
+ if(iter != End())
{
- if( Dali::CaseInsensitiveStringCompare(iter->key, key ))
- {
- // Const cast because of const_iterator. const_iterator because, STL.
- result = const_cast<EntryType*>(&(iter->entry));
- }
+ return const_cast<EntryType*>(&(iter->entry));
}
}
- return result;
+ return nullptr;
}
- /**
- * Find the element in the dictionary pointed at by key using a case
- * insensitive search, and return a const pointer to it, or NULL
- */
- const EntryType* FindCaseInsensitiveC( const char* key ) const
+ iterator Begin() const
{
- if( key != NULL )
- {
- std::string theKey(key);
- return FindCaseInsensitiveC( theKey );
- }
- return NULL;
+ return container.cbegin();
}
/**
- * Find the element in the dictionary pointed at by key using a case
- * insensitive search, and return a non-const pointer to it, or NULL
+ * Return an iterator pointing past the last entry in the dictionary
*/
- EntryType* FindCaseInsensitive( const char* key ) const
+ iterator End() const
{
- if( key != NULL )
- {
- std::string theKey(key);
- return FindCaseInsensitive( theKey );
- }
- return NULL;
+ return container.cend();
}
- /**
- * Return an iterator pointing at the first entry in the dictionary
- */
- typename Elements::const_iterator Begin() const
+ void GetKeys( DictionaryKeys& keys ) const
{
- return container.begin();
+ keys.clear();
+ for(const auto& element : container)
+ {
+ keys.push_back(element.key);
+ }
}
- /**
- * Return an iterator pointing past the last entry in the dictionary
- */
- typename Elements::const_iterator End() const
+ void Clear()
{
- return container.end();
+ container.clear();
}
};