Skip to content

Commit

Permalink
3.14.06
Browse files Browse the repository at this point in the history
  • Loading branch information
rparolin committed Oct 16, 2019
1 parent 5dc6eee commit 7b39afe
Show file tree
Hide file tree
Showing 17 changed files with 446 additions and 131 deletions.
91 changes: 91 additions & 0 deletions include/EASTL/finally.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/////////////////////////////////////////////////////////////////////////////
// Copyright (c) Electronic Arts Inc. All rights reserved.
/////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// eastl::finally is an implementation of the popular cpp idiom RAII - Resource
// Acquisition Is Initialization. eastl::finally guarantees that the user
// provided callable will be executed upon whatever mechanism is used to leave
// the current scope. This can guard against user errors but this is a popular
// technique to write robust code in execution environments that have exceptions
// enabled.
//
// Example:
// void foo()
// {
// void* p = malloc(128);
// auto _ = eastl::make_finally([&] { free(p); });
//
// // Code that may throw an exception...
//
// } // eastl::finally guaranteed to call 'free' at scope exit.
//
// References:
// * https://www.bfilipek.com/2017/04/finalact.html
///////////////////////////////////////////////////////////////////////////////

#ifndef EASTL_FINALLY_H
#define EASTL_FINALLY_H

#if defined(EA_PRAGMA_ONCE_SUPPORTED)
#pragma once
#endif

#include <EASTL/internal/config.h>

namespace eastl
{
///////////////////////////////////////////////////////////////////////////
// finally
//
// finally is the type that calls the users callback on scope exit.
//
template <typename Functor>
class finally
{
static_assert(!eastl::is_lvalue_reference_v<Functor>, "eastl::finally requires the callable is passed as an rvalue reference.");

Functor m_functor;
bool m_engaged = false;

public:
finally(Functor f) : m_functor(eastl::move(f)), m_engaged(true) {}

finally(finally&& other) : m_functor(eastl::move(other.m_functor)), m_engaged(other.m_engaged)
{
other.dismiss();
}

~finally() { execute(); }

finally(const finally&) = delete;
finally& operator=(const finally&) = delete;
finally& operator=(finally&&) = delete;

inline void dismiss() { m_engaged = false; }

inline void execute()
{
if (m_engaged)
m_functor();

dismiss();
}
};


///////////////////////////////////////////////////////////////////////////
// make_finally
//
// this utility function is the standard mechansim to perform the required
// type deduction on the users provided callback inorder to create a
// 'finally' object.
//
template <typename F>
auto make_finally(F&& f)
{
return finally<F>(eastl::forward<F>(f));
}
}

#endif // EASTL_FINALLY_H
2 changes: 1 addition & 1 deletion include/EASTL/fixed_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ namespace eastl
char mBuffer[fixed_allocator_type::kBufferSize]; // kBufferSize will take into account alignment requirements.

using base_type::mAllocator;
using base_type::get_compare;
using base_type::get_compare;

public:
fixed_multimap();
Expand Down
2 changes: 1 addition & 1 deletion include/EASTL/fixed_set.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ namespace eastl
char mBuffer[fixed_allocator_type::kBufferSize]; // kBufferSize will take into account alignment requirements.

using base_type::mAllocator;
using base_type::get_compare;
using base_type::get_compare;

public:
fixed_set();
Expand Down
4 changes: 2 additions & 2 deletions include/EASTL/internal/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@
///////////////////////////////////////////////////////////////////////////////

#ifndef EASTL_VERSION
#define EASTL_VERSION "3.14.03"
#define EASTL_VERSION_N 31403
#define EASTL_VERSION "3.14.06"
#define EASTL_VERSION_N 31406
#endif


Expand Down
135 changes: 70 additions & 65 deletions include/EASTL/internal/red_black_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,53 +184,65 @@ namespace eastl
}; // rbtree_iterator


///////////////////////////////////////////////////////////////////////////////
// rb_base_compare_ebo
//
// Utilizes the "empty base-class optimization" to reduce the size of the rbtree
// when its Compare template argument is an empty class.
///////////////////////////////////////////////////////////////////////////////

template <typename Compare, bool /*isEmpty*/ = is_empty<Compare>::value>
struct rb_base_compare_ebo
{
protected:
rb_base_compare_ebo() : mCompare() {}
rb_base_compare_ebo(const Compare& compare) : mCompare(compare) {}

Compare& get_compare() { return mCompare; }
const Compare& get_compare() const { return mCompare; }

///////////////////////////////////////////////////////////////////////////////
// rb_base_compare_ebo
//
// Utilizes the "empty base-class optimization" to reduce the size of the rbtree
// when its Compare template argument is an empty class.
///////////////////////////////////////////////////////////////////////////////

template <typename Compare, bool /*isEmpty*/ = is_empty<Compare>::value>
struct rb_base_compare_ebo
{
protected:
rb_base_compare_ebo() : mCompare() {}
rb_base_compare_ebo(const Compare& compare) : mCompare(compare) {}

Compare& get_compare() { return mCompare; }
const Compare& get_compare() const { return mCompare; }

template <typename T>
bool compare(const T& lhs, const T& rhs) const { return mCompare(lhs, rhs); }
template <typename T>
bool compare(const T& lhs, const T& rhs)
{
return mCompare(lhs, rhs);
}

private:
Compare mCompare;
};
template <typename T>
bool compare(const T& lhs, const T& rhs) const
{
return mCompare(lhs, rhs);
}

template <typename Compare>
struct rb_base_compare_ebo<Compare, true>
: private Compare
{
protected:
rb_base_compare_ebo() {}
rb_base_compare_ebo(const Compare& compare) : Compare(compare) {}
private:
Compare mCompare;
};

Compare& get_compare() { return *this; }
const Compare& get_compare() const { return *this; }
template <typename Compare>
struct rb_base_compare_ebo<Compare, true> : private Compare
{
protected:
rb_base_compare_ebo() {}
rb_base_compare_ebo(const Compare& compare) : Compare(compare) {}

template <typename T>
bool compare(const T& lhs, const T& rhs) const { return Compare::operator()(lhs, rhs); }
};
Compare& get_compare() { return *this; }
const Compare& get_compare() const { return *this; }

template <typename T>
bool compare(const T& lhs, const T& rhs)
{
return Compare::operator()(lhs, rhs);
}

template <typename T>
bool compare(const T& lhs, const T& rhs) const
{
return Compare::operator()(lhs, rhs);
}
};



///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// rb_base
//
// This class allows us to use a generic rbtree as the basis of map, multimap,
Expand All @@ -252,14 +264,13 @@ namespace eastl
/// will be the same as each other and ExtractKey will be eastl::use_self.
///
template <typename Key, typename Value, typename Compare, typename ExtractKey, bool bUniqueKeys, typename RBTree>
struct rb_base
: public rb_base_compare_ebo<Compare>
struct rb_base : public rb_base_compare_ebo<Compare>
{
typedef ExtractKey extract_key;

protected:
using rb_base_compare_ebo<Compare>::compare;
using rb_base_compare_ebo<Compare>::get_compare;
protected:
using rb_base_compare_ebo<Compare>::compare;
using rb_base_compare_ebo<Compare>::get_compare;

public:
rb_base() {}
Expand All @@ -273,60 +284,54 @@ namespace eastl
/// other and ExtractKey will be eastl::use_self.
///
template <typename Key, typename Value, typename Compare, typename ExtractKey, typename RBTree>
struct rb_base<Key, Value, Compare, ExtractKey, false, RBTree>
: public rb_base_compare_ebo<Compare>
struct rb_base<Key, Value, Compare, ExtractKey, false, RBTree> : public rb_base_compare_ebo<Compare>
{
typedef ExtractKey extract_key;

protected:
using rb_base_compare_ebo<Compare>::compare;
using rb_base_compare_ebo<Compare>::get_compare;
protected:
using rb_base_compare_ebo<Compare>::compare;
using rb_base_compare_ebo<Compare>::get_compare;

public:
rb_base() {}
rb_base(const Compare& compare) : rb_base_compare_ebo<Compare>(compare) {}
rb_base() {}
rb_base(const Compare& compare) : rb_base_compare_ebo<Compare>(compare) {}
};


/// rb_base
/// This specialization is used for 'map'.
///
template <typename Key, typename Pair, typename Compare, typename RBTree>
struct rb_base<Key, Pair, Compare, eastl::use_first<Pair>, true, RBTree>
: public rb_base_compare_ebo<Compare>
struct rb_base<Key, Pair, Compare, eastl::use_first<Pair>, true, RBTree> : public rb_base_compare_ebo<Compare>
{
typedef eastl::use_first<Pair> extract_key;

using rb_base_compare_ebo<Compare>::compare;
using rb_base_compare_ebo<Compare>::get_compare;
using rb_base_compare_ebo<Compare>::compare;
using rb_base_compare_ebo<Compare>::get_compare;

public:
rb_base() {}
rb_base(const Compare& compare) : rb_base_compare_ebo<Compare>(compare) {}
rb_base() {}
rb_base(const Compare& compare) : rb_base_compare_ebo<Compare>(compare) {}
};


/// rb_base
/// This specialization is used for 'multimap'.
///
template <typename Key, typename Pair, typename Compare, typename RBTree>
struct rb_base<Key, Pair, Compare, eastl::use_first<Pair>, false, RBTree>
: public rb_base_compare_ebo<Compare>
struct rb_base<Key, Pair, Compare, eastl::use_first<Pair>, false, RBTree> : public rb_base_compare_ebo<Compare>
{
typedef eastl::use_first<Pair> extract_key;

using rb_base_compare_ebo<Compare>::compare;
using rb_base_compare_ebo<Compare>::get_compare;
using rb_base_compare_ebo<Compare>::compare;
using rb_base_compare_ebo<Compare>::get_compare;

public:
rb_base() {}
rb_base(const Compare& compare) : rb_base_compare_ebo<Compare>(compare) {}
rb_base() {}
rb_base(const Compare& compare) : rb_base_compare_ebo<Compare>(compare) {}
};





/// rbtree
///
/// rbtree is the red-black tree basis for the map, multimap, set, and multiset
Expand Down Expand Up @@ -408,9 +413,9 @@ namespace eastl
typedef integral_constant<bool, bUniqueKeys> has_unique_keys_type;
typedef typename base_type::extract_key extract_key;

protected:
using base_type::compare;
using base_type::get_compare;
protected:
using base_type::compare;
using base_type::get_compare;

public:
rbtree_node_base mAnchor; /// This node acts as end() and its mpLeft points to begin(), and mpRight points to rbegin() (the last node on the right).
Expand Down
20 changes: 10 additions & 10 deletions include/EASTL/list.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,15 +217,15 @@ namespace eastl
#endif

protected:
eastl::compressed_pair<base_node_type, allocator_type> mNodeAllocator;
eastl::compressed_pair<base_node_type, allocator_type> mNodeAllocator;
#if EASTL_LIST_SIZE_CACHE
size_type mSize;
#endif

base_node_type& internalNode() EA_NOEXCEPT { return mNodeAllocator.first(); }
base_node_type const& internalNode() const EA_NOEXCEPT { return mNodeAllocator.first(); }
allocator_type& internalAllocator() EA_NOEXCEPT { return mNodeAllocator.second(); }
const allocator_type& internalAllocator() const EA_NOEXCEPT { return mNodeAllocator.second(); }
base_node_type& internalNode() EA_NOEXCEPT { return mNodeAllocator.first(); }
base_node_type const& internalNode() const EA_NOEXCEPT { return mNodeAllocator.first(); }
allocator_type& internalAllocator() EA_NOEXCEPT { return mNodeAllocator.second(); }
const allocator_type& internalAllocator() const EA_NOEXCEPT { return mNodeAllocator.second(); }

public:
const allocator_type& get_allocator() const EA_NOEXCEPT;
Expand Down Expand Up @@ -304,8 +304,8 @@ namespace eastl
#if EASTL_LIST_SIZE_CACHE
using base_type::mSize;
#endif
using base_type::internalNode;
using base_type::internalAllocator;
using base_type::internalNode;
using base_type::internalAllocator;

public:
list();
Expand Down Expand Up @@ -718,7 +718,7 @@ namespace eastl

template <typename T, typename Allocator>
inline ListBase<T, Allocator>::ListBase()
: mNodeAllocator(base_node_type(), allocator_type(EASTL_LIST_DEFAULT_NAME))
: mNodeAllocator(base_node_type(), allocator_type(EASTL_LIST_DEFAULT_NAME))
#if EASTL_LIST_SIZE_CACHE
, mSize(0)
#endif
Expand Down Expand Up @@ -788,8 +788,8 @@ namespace eastl
template <typename T, typename Allocator>
inline void ListBase<T, Allocator>::DoInit() EA_NOEXCEPT
{
internalNode().mpNext = (ListNode<T>*)&internalNode();
internalNode().mpPrev = (ListNode<T>*)&internalNode();
internalNode().mpNext = (ListNode<T>*)&internalNode();
internalNode().mpPrev = (ListNode<T>*)&internalNode();
}


Expand Down
Loading

0 comments on commit 7b39afe

Please sign in to comment.