Partial update.

Added link_after to forward_link.
Added SAFE option to bidirectional_link
This commit is contained in:
jwellbelove 2016-01-25 12:37:41 +00:00
parent 189cde576f
commit fa1284d7ed

View File

@ -33,6 +33,11 @@ SOFTWARE.
#include "nullptr.h"
#include "type_traits.h"
#include "exception.h"
#include "error_handler.h"
#undef ETL_FILE
#define ETL_FILE "23"
namespace etl
{
@ -40,11 +45,26 @@ namespace etl
{
enum
{
NO_AUTO_UNLINK = false,
AUTO_UNLINK = true
DEFAULT = 0,
AUTO = 1,
SAFE = 2
};
};
//***************************************************************************
/// Deque full exception.
///\ingroup deque
//***************************************************************************
class link_exception : public etl::exception
{
public:
link_exception(string_type file_name, numeric_type line_number)
: exception(ETL_ERROR_TEXT("link:still linked", ETL_FILE"A"), file_name, line_number)
{
}
};
//***************************************************************************
/// A forward link.
//***************************************************************************
@ -72,6 +92,15 @@ namespace etl
lhs.etl_next = &rhs;
}
// Reference, Reference
template <typename TLink>
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type
link_insert(TLink& lhs, TLink& rhs)
{
rhs.etl_next = lhs.etl_next;
lhs.etl_next = &rhs;
}
// Pointer, Pointer
template <typename TLink>
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type
@ -83,6 +112,22 @@ namespace etl
}
}
// Pointer, Pointer
template <typename TLink>
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type
link_insert(TLink* lhs, TLink* rhs)
{
if (lhs != nullptr)
{
if (rhs != nullptr)
{
rhs->etl_next = lhs->etl_next;
}
lhs->etl_next = rhs;
}
}
// Reference, Pointer
template <typename TLink>
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type
@ -91,6 +136,19 @@ namespace etl
lhs.etl_next = rhs;
}
// Reference, Pointer
template <typename TLink>
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type
link_insert(TLink& lhs, TLink* rhs)
{
if (rhs != nullptr)
{
rhs->etl_next = lhs.etl_next;
}
lhs.etl_next = rhs;
}
// Pointer, Reference
template <typename TLink>
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type
@ -102,6 +160,18 @@ namespace etl
}
}
// Pointer, Reference
template <typename TLink>
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type
link_insert(TLink* lhs, TLink& rhs)
{
if (lhs != nullptr)
{
rhs.etl_next = lhs->etl_next;
lhs->etl_next = &rhs;
}
}
// Reference
template <typename TLink>
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type
@ -130,7 +200,7 @@ namespace etl
//***************************************************************************
/// A bidirectional link.
//***************************************************************************
template <const size_t ID_ = 0, const bool OPTION_ = etl::link_option::NO_AUTO_UNLINK>
template <const size_t ID_ = 0, const int OPTION_ = etl::link_option::DEFAULT>
struct bidirectional_link
{
enum
@ -149,10 +219,12 @@ namespace etl
bidirectional_link* etl_next;
};
//******************************************************************
// Specialisation for auto unlinked option.
// When this link is destroyed it will automatically unlink itself.
//******************************************************************
template <const size_t ID_>
struct bidirectional_link<ID_, etl::link_option::AUTO_UNLINK>
struct bidirectional_link<ID_, etl::link_option::AUTO>
{
enum
{
@ -185,6 +257,36 @@ namespace etl
bidirectional_link* etl_next;
};
//******************************************************************
// Specialisation for safe unlinked option.
// An error will be generated if the links are valid when the object
// is destroyed.
//******************************************************************
template <const size_t ID_>
struct bidirectional_link<ID_, etl::link_option::SAFE>
{
enum
{
ID = ID_,
OPTION = etl::link_option::AUTO_UNLINK
};
~bidirectional_link()
{
ETL_ASSERT(etl_previous == nullptr, ETL_ERROR(link_exception));
ETL_ASSERT(etl_next == nullptr, ETL_ERROR(link_exception));
}
void clear()
{
etl_previous = nullptr;
etl_next = nullptr;
}
bidirectional_link* etl_previous;
bidirectional_link* etl_next;
};
// Reference, Reference
template <typename TLink>
typename etl::enable_if<etl::is_same<TLink, etl::bidirectional_link<TLink::ID, TLink::OPTION> >::value, void>::type
@ -393,4 +495,5 @@ namespace etl
}
}
#undef ETL_FILE
#endif