Loading...
Searching...
No Matches
reference_counted_object.h
// The MIT License(MIT)
//
// Embedded Template Library.
// https://github.com/ETLCPP/etl
// https://www.etlcpp.com
//
// Copyright(c) 2021 John Wellbelove
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//******************************************************************************/
#ifndef ETL_REFERENCE_COUNTED_OBJECT_INCLUDED
#define ETL_REFERENCE_COUNTED_OBJECT_INCLUDED
#include "platform.h"
#include "atomic.h"
#include "error_handler.h"
#include "exception.h"
#include "utility.h"
#include <stdint.h>
namespace etl
{
//***************************************************************************
//***************************************************************************
class reference_counting_exception : public etl::exception
{
public:
reference_counting_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
: exception(reason_, file_name_, line_number_)
{
}
};
//***************************************************************************
//***************************************************************************
class reference_count_overrun : public etl::reference_counting_exception
{
public:
reference_count_overrun(string_type file_name_, numeric_type line_number_)
: etl::reference_counting_exception(ETL_ERROR_TEXT("reference_counting:overrun", ETL_REFERENCE_COUNTED_OBJECT_FILE_ID"A"), file_name_,
line_number_)
{
}
};
//***************************************************************************
//***************************************************************************
class ireference_counter
{
public:
virtual ~ireference_counter() {}
virtual void set_reference_count(int32_t value) = 0;
virtual void increment_reference_count() = 0;
ETL_NODISCARD
virtual int32_t decrement_reference_count() = 0;
ETL_NODISCARD
virtual int32_t get_reference_count() const = 0;
};
//***************************************************************************
//***************************************************************************
template <typename TCounter>
class reference_counter : public ireference_counter
{
public:
//***************************************************************************
//***************************************************************************
reference_counter()
: reference_count(0)
{
}
//***************************************************************************
//***************************************************************************
virtual void set_reference_count(int32_t value) ETL_OVERRIDE
{
reference_count = value;
}
//***************************************************************************
//***************************************************************************
virtual void increment_reference_count() ETL_OVERRIDE
{
++reference_count;
}
//***************************************************************************
//***************************************************************************
ETL_NODISCARD
virtual int32_t decrement_reference_count() ETL_OVERRIDE
{
ETL_ASSERT(reference_count > 0, ETL_ERROR(reference_count_overrun));
return int32_t(--reference_count);
}
//***************************************************************************
//***************************************************************************
ETL_NODISCARD
virtual int32_t get_reference_count() const ETL_OVERRIDE
{
return int32_t(reference_count);
}
private:
TCounter reference_count; // The reference count object.
};
//***************************************************************************
//***************************************************************************
template <>
class reference_counter<void> : public ireference_counter
{
public:
//***************************************************************************
//***************************************************************************
reference_counter()
{
// Do nothing.
}
//***************************************************************************
//***************************************************************************
virtual void set_reference_count(int32_t /*value*/) ETL_OVERRIDE
{
// Do nothing.
}
//***************************************************************************
//***************************************************************************
virtual void increment_reference_count() ETL_OVERRIDE
{
// Do nothing.
}
//***************************************************************************
//***************************************************************************
ETL_NODISCARD
virtual int32_t decrement_reference_count() ETL_OVERRIDE
{
return 1;
}
//***************************************************************************
//***************************************************************************
ETL_NODISCARD
virtual int32_t get_reference_count() const ETL_OVERRIDE
{
return 1;
}
};
//***************************************************************************
//***************************************************************************
class ireference_counted_object
{
public:
virtual ~ireference_counted_object() {}
ETL_NODISCARD
virtual ireference_counter& get_reference_counter() = 0;
ETL_NODISCARD
virtual const ireference_counter& get_reference_counter() const = 0;
};
//***************************************************************************
//***************************************************************************
template <typename TObject, typename TCounter>
class reference_counted_object : public etl::ireference_counted_object
{
public:
typedef TObject value_type;
typedef TCounter counter_type;
//***************************************************************************
//***************************************************************************
reference_counted_object() {}
//***************************************************************************
//***************************************************************************
reference_counted_object(const TObject& object_)
: object(object_)
{
}
#if ETL_USING_CPP11
//***************************************************************************
//***************************************************************************
template <typename... TArgs>
reference_counted_object(TArgs&&... args)
: object(etl::forward<TArgs>(args)...)
{
}
#endif
//***************************************************************************
//***************************************************************************
ETL_NODISCARD
value_type& get_object()
{
return object;
}
//***************************************************************************
//***************************************************************************
ETL_NODISCARD
const value_type& get_object() const
{
return object;
}
//***************************************************************************
//***************************************************************************
ETL_NODISCARD
virtual ireference_counter& get_reference_counter() ETL_OVERRIDE
{
return reference_counter;
}
//***************************************************************************
//***************************************************************************
ETL_NODISCARD
virtual const ireference_counter& get_reference_counter() const ETL_OVERRIDE
{
return reference_counter;
}
private:
// This class must not be copy constructed or assigned.
reference_counted_object(const reference_counted_object&) ETL_DELETE;
reference_counted_object& operator=(const reference_counted_object&) ETL_DELETE;
TObject object;
etl::reference_counter<TCounter> reference_counter;
};
#if ETL_USING_CPP11 && ETL_HAS_ATOMIC
//***************************************************************************
//***************************************************************************
template <typename TObject>
using atomic_counted_object = etl::reference_counted_object<TObject, etl::atomic_int32_t>;
#endif
} // namespace etl
#endif
etl::ireference_counted_object
Base for all reference counted objects.
Definition reference_counted_object.h:200
etl::ireference_counter
The base of all reference counters.
Definition reference_counted_object.h:76
etl::reference_count_overrun
Definition reference_counted_object.h:62
etl::reference_counted_object
Definition reference_counted_object.h:217
etl::reference_counted_object::get_reference_counter
virtual ETL_NODISCARD ireference_counter & get_reference_counter() ETL_OVERRIDE
Get a reference to the reference counter.
Definition reference_counted_object.h:269
etl::reference_counted_object::reference_counted_object
reference_counted_object()
Constructor.
Definition reference_counted_object.h:226
etl::reference_counted_object::get_object
ETL_NODISCARD value_type & get_object()
Get a reference to the counted object.
Definition reference_counted_object.h:251
etl::reference_counted_object::reference_counted_object
reference_counted_object(const TObject &object_)
Constructor.
Definition reference_counted_object.h:231
etl::reference_counted_object::get_reference_counter
virtual ETL_NODISCARD const ireference_counter & get_reference_counter() const ETL_OVERRIDE
Get a const reference to the reference counter.
Definition reference_counted_object.h:278
etl::reference_counted_object::get_object
ETL_NODISCARD const value_type & get_object() const
Get a const reference to the counted object.
Definition reference_counted_object.h:260
etl::reference_counter< void >::reference_counter
reference_counter()
Constructor.
Definition reference_counted_object.h:156
etl::reference_counter< void >::set_reference_count
virtual void set_reference_count(int32_t) ETL_OVERRIDE
Set the reference count.
Definition reference_counted_object.h:164
etl::reference_counter< void >::get_reference_count
virtual ETL_NODISCARD int32_t get_reference_count() const ETL_OVERRIDE
Get the current reference count.
Definition reference_counted_object.h:190
etl::reference_counter< void >::increment_reference_count
virtual void increment_reference_count() ETL_OVERRIDE
Increment the reference count.
Definition reference_counted_object.h:172
etl::reference_counter< void >::decrement_reference_count
virtual ETL_NODISCARD int32_t decrement_reference_count() ETL_OVERRIDE
Decrement the reference count.
Definition reference_counted_object.h:181
etl::reference_counter
A specific type of reference counter.
Definition reference_counted_object.h:93
etl::reference_counter::get_reference_count
virtual ETL_NODISCARD int32_t get_reference_count() const ETL_OVERRIDE
Get the current reference count.
Definition reference_counted_object.h:135
etl::reference_counter::increment_reference_count
virtual void increment_reference_count() ETL_OVERRIDE
Increment the reference count.
Definition reference_counted_object.h:115
etl::reference_counter::reference_counter
reference_counter()
Constructor.
Definition reference_counted_object.h:99
etl::reference_counter::set_reference_count
virtual void set_reference_count(int32_t value) ETL_OVERRIDE
Set the reference count.
Definition reference_counted_object.h:107
etl::reference_counter::decrement_reference_count
virtual ETL_NODISCARD int32_t decrement_reference_count() ETL_OVERRIDE
Decrement the reference count.
Definition reference_counted_object.h:124
etl::reference_counting_exception
Definition reference_counted_object.h:48
error_handler.h
exception.h
ETL_ASSERT
#define ETL_ASSERT(b, e)
Definition error_handler.h:511
etl::exception::exception
ETL_EXCEPTION_CONSTEXPR exception(string_type reason_, string_type, numeric_type)
Constructor.
Definition exception.h:81
etl::exception
Definition exception.h:59
etl
Definition absolute.h:40
platform.h
utility.h