diff --git a/doc/EASTL.natvis b/doc/EASTL.natvis
index d3095ec1..30986d5e 100644
--- a/doc/EASTL.natvis
+++ b/doc/EASTL.natvis
@@ -553,6 +553,12 @@
+
+
+ {mFlag.mAtomic}
+
+
+
diff --git a/include/EASTL/bonus/lru_cache.h b/include/EASTL/bonus/lru_cache.h
index 5c1c32e3..46d053dc 100644
--- a/include/EASTL/bonus/lru_cache.h
+++ b/include/EASTL/bonus/lru_cache.h
@@ -66,10 +66,16 @@ namespace eastl
/// All accesses to a given key (insert, update, get) will push that key to most recently used.
/// If the data objects are shared between threads, it would be best to use a smartptr to manage the lifetime of the data.
/// as it could be removed from the cache while in use by another thread.
- template ,
- typename map_type = eastl::unordered_map, eastl::hash, eastl::equal_to, Allocator > >
- class lru_cache
+ template ,
+ typename map_type = eastl::unordered_map,
+ eastl::hash,
+ eastl::equal_to,
+ Allocator>>
+ class lru_cache
{
public:
using key_type = Key;
@@ -81,9 +87,9 @@ namespace eastl
using data_container_type = eastl::pair;
using iterator = typename map_type::iterator;
using const_iterator = typename map_type::const_iterator;
- using this_type = lru_cache ;
+ using this_type = lru_cache;
using create_callback_type = eastl::function;
- using delete_callback_type = eastl::function;
+ using delete_callback_type = eastl::function;
/// lru_cache constructor
///
@@ -91,7 +97,7 @@ namespace eastl
/// For complex objects or operations, the creator and deletor callbacks can be used.
/// This works just like a regular map object: on access, the Value will be created if it doesn't exist, returned otherwise.
explicit lru_cache(size_type size,
- const allocator_type &allocator = EASTL_LRUCACHE_DEFAULT_ALLOCATOR,
+ const allocator_type& allocator = EASTL_LRUCACHE_DEFAULT_ALLOCATOR,
create_callback_type creator = nullptr,
delete_callback_type deletor = nullptr)
: m_list(allocator)
@@ -99,7 +105,8 @@ namespace eastl
, m_capacity(size)
, m_create_callback(creator)
, m_delete_callback(deletor)
- {}
+ {
+ }
/// lru_cache destructor
///
@@ -107,13 +114,22 @@ namespace eastl
~lru_cache()
{
// Destruct everything we have cached
- for (auto &iter : m_map)
+ for (auto& iter : m_map)
{
- if (m_delete_callback) m_delete_callback(iter.second.first);
+ if (m_delete_callback)
+ m_delete_callback(iter.second.first);
}
}
- lru_cache(this_type &) = delete;
+ lru_cache(std::initializer_list> il)
+ : lru_cache(il.size())
+ {
+ for(auto& p : il)
+ insert_or_assign(p.first, p.second);
+ }
+
+ // TODO(rparolin): Why do we prevent copies? And what about moves?
+ lru_cache(const this_type&) = delete;
this_type &operator=(const this_type&) = delete;
/// insert
@@ -121,7 +137,7 @@ namespace eastl
/// insert key k with value v.
/// If key already exists, no change is made and the return value is false.
/// If the key doesn't exist, the data is added to the map and the return value is true.
- bool insert(const key_type &k, const value_type &v)
+ bool insert(const key_type& k, const value_type& v)
{
if (m_map.find(k) == m_map.end())
{
@@ -143,7 +159,7 @@ namespace eastl
/// Places a new object in place k created with args
/// If the key already exists, it is replaced.
template
- void emplace(const key_type &k, Args&&... args)
+ void emplace(const key_type& k, Args&&... args)
{
make_space();
@@ -155,7 +171,7 @@ namespace eastl
///
/// Same as add, but replaces the data at key k, if it exists, with the new entry v
/// Note that the deletor for the old v will be called before it's replaced with the new value of v
- void insert_or_assign(const key_type &k, const value_type &v)
+ void insert_or_assign(const key_type& k, const value_type& v)
{
auto iter = m_map.find(k);
@@ -172,7 +188,7 @@ namespace eastl
/// contains
///
/// Returns true if key k exists in the cache
- bool contains(const key_type &k) const
+ bool contains(const key_type& k) const
{
return m_map.find(k) != m_map.end();
}
@@ -180,7 +196,7 @@ namespace eastl
/// at
///
/// Retrives the data for key k, not valid if k does not exist
- eastl::optional at(const key_type &k)
+ eastl::optional at(const key_type& k)
{
auto iter = m_map.find(k);
@@ -198,7 +214,7 @@ namespace eastl
///
/// Retrives the data for key k. If no data exists, it will be created by calling the
/// creator.
- value_type &get(const key_type &k)
+ value_type& get(const key_type& k)
{
auto iter = m_map.find(k);
@@ -219,13 +235,13 @@ namespace eastl
}
/// Equivalent to get(k)
- value_type &operator[](const key_type &k) { return get(k); }
+ value_type& operator[](const key_type& k) { return get(k); }
/// erase
///
/// erases key k from the cache.
/// If k does not exist, returns false. If k exists, returns true.
- bool erase(const key_type &k)
+ bool erase(const key_type& k)
{
auto iter = m_map.find(k);
@@ -259,7 +275,7 @@ namespace eastl
///
/// Touches key k, marking it as most recently used.
/// If k does not exist, returns false. If the touch was successful, returns true.
- bool touch(const key_type &k)
+ bool touch(const key_type& k)
{
auto iter = m_map.find(k);
@@ -275,7 +291,7 @@ namespace eastl
/// touch
///
/// Touches key at iterator iter, moving it to most recently used position
- void touch(iterator &iter)
+ void touch(iterator& iter)
{
auto listRef = iter->second.second;
@@ -289,7 +305,7 @@ namespace eastl
/// Updates key k with data v.
/// If key k does not exist, returns false and no changes are made.
/// If key k exists, existing data has its deletor called and key k's data is replaced with new v data
- bool assign(const key_type &k, const value_type &v)
+ bool assign(const key_type& k, const value_type& v)
{
auto iter = m_map.find(k);
@@ -305,7 +321,7 @@ namespace eastl
/// assign
///
/// Updates data at spot iter with data v.
- void assign(iterator &iter, const value_type &v)
+ void assign(iterator& iter, const value_type& v)
{
if (m_delete_callback)
m_delete_callback(iter->second.first);
@@ -314,21 +330,21 @@ namespace eastl
}
// standard container functions
- iterator begin() EA_NOEXCEPT { return m_map.begin(); }
- iterator end() EA_NOEXCEPT { return m_map.end(); }
- iterator rbegin() EA_NOEXCEPT { return m_map.rbegin(); }
- iterator rend() EA_NOEXCEPT { return m_map.rend(); }
- const_iterator begin() const EA_NOEXCEPT { return m_map.begin(); }
- const_iterator cbegin() const EA_NOEXCEPT { return m_map.cbegin(); }
- const_iterator crbegin() const EA_NOEXCEPT { return m_map.crbegin(); }
- const_iterator end() const EA_NOEXCEPT { return m_map.end(); }
- const_iterator cend() const EA_NOEXCEPT { return m_map.cend(); }
- const_iterator crend() const EA_NOEXCEPT { return m_map.crend(); }
-
- bool empty() const EA_NOEXCEPT { return m_map.empty(); }
- size_type size() const EA_NOEXCEPT { return m_map.size(); }
- size_type capacity() const EA_NOEXCEPT { return m_capacity; }
-
+ iterator begin() EA_NOEXCEPT { return m_map.begin(); }
+ iterator end() EA_NOEXCEPT { return m_map.end(); }
+ iterator rbegin() EA_NOEXCEPT { return m_map.rbegin(); }
+ iterator rend() EA_NOEXCEPT { return m_map.rend(); }
+ const_iterator begin() const EA_NOEXCEPT { return m_map.begin(); }
+ const_iterator cbegin() const EA_NOEXCEPT { return m_map.cbegin(); }
+ const_iterator crbegin() const EA_NOEXCEPT { return m_map.crbegin(); }
+ const_iterator end() const EA_NOEXCEPT { return m_map.end(); }
+ const_iterator cend() const EA_NOEXCEPT { return m_map.cend(); }
+ const_iterator crend() const EA_NOEXCEPT { return m_map.crend(); }
+
+ bool empty() const EA_NOEXCEPT { return m_map.empty(); }
+ size_type size() const EA_NOEXCEPT { return m_map.size(); }
+ size_type capacity() const EA_NOEXCEPT { return m_capacity; }
+
void clear() EA_NOEXCEPT
{
// Since we have a delete callback, we want to reuse the trim function by cheating the max
@@ -394,6 +410,7 @@ namespace eastl
}
}
+ private:
list_type m_list;
map_type m_map;
size_type m_capacity;
diff --git a/include/EASTL/internal/atomic/arch/x86/arch_x86_memory_barrier.h b/include/EASTL/internal/atomic/arch/x86/arch_x86_memory_barrier.h
index 78eba24d..1d1c8fca 100644
--- a/include/EASTL/internal/atomic/arch/x86/arch_x86_memory_barrier.h
+++ b/include/EASTL/internal/atomic/arch/x86/arch_x86_memory_barrier.h
@@ -27,9 +27,11 @@
#if 1
+ // 4459 : declaration of 'identifier' hides global declaration
+ // 4456 : declaration of 'identifier' hides previous local declaration
#define EASTL_ARCH_ATOMIC_CPU_MB() \
{ \
- EA_DISABLE_VC_WARNING(4456); \
+ EA_DISABLE_VC_WARNING(4459 4456); \
volatile long _; \
_InterlockedExchangeAdd(&_, 0); \
EA_RESTORE_VC_WARNING(); \
diff --git a/include/EASTL/internal/config.h b/include/EASTL/internal/config.h
index e06e530f..c016c920 100644
--- a/include/EASTL/internal/config.h
+++ b/include/EASTL/internal/config.h
@@ -89,8 +89,8 @@
///////////////////////////////////////////////////////////////////////////////
#ifndef EASTL_VERSION
- #define EASTL_VERSION "3.17.01"
- #define EASTL_VERSION_N 31701
+ #define EASTL_VERSION "3.17.03"
+ #define EASTL_VERSION_N 31703
#endif
diff --git a/test/source/TestLruCache.cpp b/test/source/TestLruCache.cpp
index fd7356a7..e6592181 100644
--- a/test/source/TestLruCache.cpp
+++ b/test/source/TestLruCache.cpp
@@ -282,5 +282,59 @@ int TestLruCache()
}
}
+ // Test iteration
+ {
+ eastl::lru_cache lc(5);
+ lc.insert_or_assign(0,10);
+ lc.insert_or_assign(1,11);
+ lc.insert_or_assign(2,12);
+ lc.insert_or_assign(3,13);
+ lc.insert_or_assign(4,14);
+
+ { // test manual for-loop
+ int i = 0;
+ for (auto b = lc.begin(), e = lc.end(); b != e; b++)
+ {
+ auto &p = *b;
+ VERIFY(i == p.first);
+ VERIFY(i + 10 == p.second.first);
+ i++;
+ }
+ }
+
+ { // test pairs
+ int i = 0;
+ for(auto& p : lc)
+ {
+ VERIFY(i == p.first);
+ VERIFY(i + 10 == p.second.first);
+ i++;
+ }
+ }
+
+ { // test structured bindings
+ int i = 0;
+ for(auto& [key, value] : lc)
+ {
+ VERIFY(i == key);
+ VERIFY(i + 10 == value.first);
+ i++;
+ }
+ }
+ }
+
+ // test initializer_list
+ {
+ eastl::lru_cache lc = {{0, 10}, {1, 11}, {2, 12}, {3, 13}, {4, 14}, {5, 15}};
+
+ int i = 0;
+ for(auto& p : lc)
+ {
+ VERIFY(i == p.first);
+ VERIFY(i + 10 == p.second.first);
+ i++;
+ }
+ }
+
return nErrorCount;
}