Merge remote-tracking branch 'origin/development'

# Conflicts:
#	include/etl/memory.h
#	include/etl/version.h
#	support/Release notes.txt
This commit is contained in:
John Wellbelove 2018-07-25 11:40:33 +01:00
parent 1f0294cb62
commit ba98ef5d79
8 changed files with 248 additions and 56 deletions

View File

@ -31,13 +31,14 @@ SOFTWARE.
#ifndef ETL_MEMORY_INCLUDED
#define ETL_MEMORY_INCLUDED
#include "algorithm.h"
#include "platform.h"
#include "algorithm.h"
#include "type_traits.h"
#include "stl/iterator.h"
#include <string.h>
///\defgroup memory memory
///\ingroup etl
namespace etl
@ -96,7 +97,7 @@ namespace etl
count += int32_t(std::distance(o_begin, o_end));
std::fill(o_begin, o_end, value);
return o_end;
}
@ -340,7 +341,7 @@ namespace etl
/// Default initialises N objects to uninitialised memory.
///\ingroup memory
//*****************************************************************************
template <typename TOutputIterator, typename TSize>
template <typename TOutputIterator, typename TSize>
typename etl::enable_if<!etl::is_trivially_constructible<typename std::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
uninitialized_default_construct_n(TOutputIterator o_begin, TSize n)
{
@ -770,12 +771,41 @@ namespace etl
};
//*****************************************************************************
/// Unique pointer.
/// Default deleter.
///\tparam T The pointed to type type.
///\ingroup memory
//*****************************************************************************
template <typename T>
class unique_ptr
struct default_delete
{
void operator()(T* p) const
{
delete p;
}
};
//*****************************************************************************
/// Default deleter for arrays.
///\tparam T The pointed to type type.
///\ingroup memory
//*****************************************************************************
template <typename T>
struct default_delete<T[]>
{
template <class U>
void operator()(U* p) const
{
delete[] p;
}
};
//*****************************************************************************
/// Unique pointer.
///\tparam T The pointed to type type.
///\ingroup memory
//*****************************************************************************
template <typename T, typename TDeleter = etl::default_delete<T> >
class unique_ptr
{
public:
@ -799,22 +829,32 @@ namespace etl
{
}
#endif
~unique_ptr()
{
delete p;
deleter(p);
}
ETL_CONSTEXPR pointer get() const
{
return p;
}
TDeleter& get_deleter()
{
return deleter;
}
const TDeleter& get_deleter() const
{
return deleter;
}
pointer release()
{
{
pointer value = p;
p = nullptr;
return value;
}
@ -826,21 +866,21 @@ namespace etl
p = p_;
delete value;
}
void swap(unique_ptr& value)
{
{
std::swap(p, value.p);
}
ETL_CONSTEXPR explicit operator bool() const
{
return (p != nullptr);
}
unique_ptr& operator =(pointer p_)
{
reset(p_);
return *this;
}
@ -848,36 +888,36 @@ namespace etl
unique_ptr& operator =(unique_ptr&& p_)
{
reset(p_.release());
return *this;
return *this;
}
#endif
ETL_CONSTEXPR reference operator *() const
{
return *get();
}
ETL_CONSTEXPR pointer operator ->() const
{
return get();
}
ETL_CONSTEXPR reference operator [](size_t i) const
{
return get()[i];
}
ETL_CONSTEXPR bool operator== (const pointer p_) const
{
return p == p_;
}
ETL_CONSTEXPR bool operator== (const unique_ptr& p_) const
{
return p == p_.p;
}
ETL_CONSTEXPR bool operator< (const unique_ptr& p_) const
{
return p < p_.p;
@ -889,25 +929,26 @@ namespace etl
unique_ptr(const unique_ptr&);
unique_ptr& operator =(const unique_ptr&);
TDeleter deleter;
pointer p;
};
//*****************************************************************************
/// Unique pointer for arrays.
///\tparam T The pointed to type type.
///\ingroup memory
//*****************************************************************************
template<typename T>
class unique_ptr<T[]>
template<typename T, typename TDeleter>
class unique_ptr<T[], TDeleter>
{
public:
typedef T element_type;
typedef T* pointer;
typedef T& reference;
ETL_CONSTEXPR unique_ptr()
ETL_CONSTEXPR unique_ptr()
: p(nullptr)
{
}
@ -916,43 +957,53 @@ namespace etl
: p(p_)
{
}
#if ETL_CPP11_SUPPORTED
unique_ptr(unique_ptr&& p_)
: p(p_.release())
{
}
#endif
~unique_ptr()
~unique_ptr()
{
delete[] p;
deleter(p);
}
ETL_CONSTEXPR pointer get() const
{
return p;
}
pointer release()
TDeleter& get_deleter()
{
return deleter;
}
const TDeleter& get_deleter() const
{
return deleter;
}
pointer release()
{
pointer value = p;
p = nullptr;
return value;
}
void reset(pointer p_)
{
assert(p_ != p);
pointer value = p;
p = p_;
delete[] value;
pointer value = p;
p = p_;
delete[] value;
}
void swap(unique_ptr& v)
{
std::swap(p, v.p);
std::swap(p, v.p);
}
ETL_CONSTEXPR explicit operator bool() const
@ -963,8 +1014,8 @@ namespace etl
unique_ptr& operator =(pointer p_)
{
reset(p_);
return *this;
return *this;
}
#if ETL_CPP11_SUPPORTED
@ -972,31 +1023,31 @@ namespace etl
{
reset(p_.release());
return *this;
return *this;
}
#endif
ETL_CONSTEXPR reference operator *() const
{
return *p;
return *p;
}
ETL_CONSTEXPR pointer operator ->() const
{
return p;
return p;
}
ETL_CONSTEXPR reference operator [](size_t i) const
{
return p[i];
return p[i];
}
ETL_CONSTEXPR bool operator ==(const pointer p_) const
{
return (p == p_);
return (p == p_);
}
ETL_CONSTEXPR bool operator ==(const unique_ptr& p_) const
ETL_CONSTEXPR bool operator ==(const unique_ptr& p_) const
{
return (p == p_.p);
}
@ -1005,14 +1056,33 @@ namespace etl
{
return (p < p_.p);
}
private:
// Deleted.
unique_ptr(const unique_ptr&);
unique_ptr& operator =(const unique_ptr&);
pointer p;
TDeleter deleter;
pointer p;
};
//*****************************************************************************
/// Base class for objects that require their memory to be wiped after use.
/// Erases the object's memory to zero.
/// Note: This <b>must</b> be the last destructor called for the derived object.
///\tparam T The derived type.
///\ingroup memory
//*****************************************************************************
template <typename T>
struct wipe_on_destruct
{
~wipe_on_destruct()
{
char* pobject = reinterpret_cast<char*>(static_cast<T*>(this));
memset(pobject, 0, sizeof(T));
}
};
}

View File

@ -37,10 +37,10 @@ SOFTWARE.
/// Definitions of the ETL version
///\ingroup utilities
#define ETL_VERSION "11.13.2"
#define ETL_VERSION "11.14.0"
#define ETL_VERSION_MAJOR 11
#define ETL_VERSION_MINOR 13
#define ETL_VERSION_PATCH 2
#define ETL_VERSION_MINOR 14
#define ETL_VERSION_PATCH 0
#endif

View File

@ -1,3 +1,9 @@
===============================================================================
11.14.0
Added tests for limited support for self insert for strings.
Added 'wipe_on_destruct' template class for secure wiping of objects on destruction.
Updated unique_ptr API.
===============================================================================
11.13.2
Protected destructor for some FSM classes.

View File

@ -528,5 +528,47 @@ namespace
CHECK_EQUAL(test_item_trivial, etl::make_copy_at(pn, test_item_trivial, count));
CHECK_EQUAL(3U, count);
}
//*************************************************************************
TEST(test_wipe_on_destruct)
{
struct Data : public etl::wipe_on_destruct<Data>
{
Data(int a_, char b_, double c_)
: a(a_),
b(b_),
c(c_)
{
}
bool operator ==(const Data& other) const
{
return (a == other.a) && (b == other.b) && (c == other.c);
}
int a;
char b;
double c;
};
std::array<char, sizeof(Data)> buffer;
buffer.fill(0);
// Construct in-place.
::new (buffer.data()) Data(1, 'b', 3.4);
Data& other = *reinterpret_cast<Data*>(buffer.data());
CHECK(other == Data(1, 'b', 3.4));
// Cleared compare buffer.
std::array<char, sizeof(Data)> clear;
clear.fill(0);
// Destruct;
other.~Data();
// Storage should be wiped.
CHECK(buffer == clear);
}
};
}

View File

@ -48,6 +48,7 @@ namespace
typedef etl::istring IText;
typedef std::string Compare_Text;
typedef Text::value_type value_t;
typedef etl::string<52> TextL;
Compare_Text initial_text;
Compare_Text less_text;
@ -867,6 +868,24 @@ namespace
CHECK(is_equal);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_insert_position_range_self)
{
size_t length = TextL::MAX_SIZE / 2;
for (size_t offset = 10; offset < length; ++offset)
{
Compare_Text compare_text = STR("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
TextL text = STR("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
text.insert(text.begin() + offset, text.begin() + 5, text.begin() + 10);
compare_text.insert(compare_text.begin() + offset, compare_text.begin() + 5, compare_text.begin() + 10);
bool is_equal = Equal(compare_text, text);
CHECK(is_equal);
}
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_insert_size_t_position_string)
{

View File

@ -47,6 +47,7 @@ namespace
typedef etl::iu16string IText;
typedef std::u16string Compare_Text;
typedef Text::value_type value_t;
typedef etl::u16string<52> TextL;
Compare_Text initial_text;
Compare_Text less_text;
@ -866,6 +867,24 @@ namespace
CHECK(is_equal);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_insert_position_range_self)
{
size_t length = TextL::MAX_SIZE / 2;
for (size_t offset = 10; offset < length; ++offset)
{
Compare_Text compare_text = STR("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
TextL text = STR("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
text.insert(text.begin() + offset, text.begin() + 5, text.begin() + 10);
compare_text.insert(compare_text.begin() + offset, compare_text.begin() + 5, compare_text.begin() + 10);
bool is_equal = Equal(compare_text, text);
CHECK(is_equal);
}
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_insert_size_t_position_string)
{

View File

@ -47,6 +47,7 @@ namespace
typedef etl::iu32string IText;
typedef std::u32string Compare_Text;
typedef Text::value_type value_t;
typedef etl::u32string<52> TextL;
Compare_Text initial_text;
Compare_Text less_text;
@ -583,8 +584,6 @@ namespace
CHECK(is_equal);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_push_back)
{
@ -866,6 +865,24 @@ namespace
CHECK(is_equal);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_insert_position_range_self)
{
size_t length = TextL::MAX_SIZE / 2;
for (size_t offset = 10; offset < length; ++offset)
{
Compare_Text compare_text = STR("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
TextL text = STR("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
text.insert(text.begin() + offset, text.begin() + 5, text.begin() + 10);
compare_text.insert(compare_text.begin() + offset, compare_text.begin() + 5, compare_text.begin() + 10);
bool is_equal = Equal(compare_text, text);
CHECK(is_equal);
}
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_insert_size_t_position_string)
{

View File

@ -47,6 +47,7 @@ namespace
typedef etl::iwstring IText;
typedef std::wstring Compare_Text;
typedef Text::value_type value_t;
typedef etl::wstring<52> TextL;
Compare_Text initial_text;
Compare_Text less_text;
@ -866,6 +867,24 @@ namespace
CHECK(is_equal);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_insert_position_range_self)
{
size_t length = TextL::MAX_SIZE / 2;
for (size_t offset = 10; offset < length; ++offset)
{
Compare_Text compare_text = STR("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
TextL text = STR("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
text.insert(text.begin() + offset, text.begin() + 5, text.begin() + 10);
compare_text.insert(compare_text.begin() + offset, compare_text.begin() + 5, compare_text.begin() + 10);
bool is_equal = Equal(compare_text, text);
CHECK(is_equal);
}
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_insert_size_t_position_string)
{