mirror of
https://github.com/ETLCPP/etl.git
synced 2026-06-16 17:06:05 +08:00
Added emplace functions to etl::variant
This commit is contained in:
parent
c43adc7df3
commit
1dd1ffc4e4
@ -1,5 +1,5 @@
|
||||
name=Embedded Template Library
|
||||
version=10.16.1
|
||||
version=10.17.0
|
||||
author= John Wellbelove <john.wellbelove@etlcpp.com>
|
||||
maintainer=John Wellbelove <john.wellbelove@etlcpp.com>
|
||||
sentence=A C++ template library tailored for embedded systems.
|
||||
|
||||
108
src/variant.h
108
src/variant.h
@ -112,6 +112,18 @@ namespace etl
|
||||
typename T8 = __private_variant__::no_type<8> >
|
||||
class variant
|
||||
{
|
||||
public:
|
||||
|
||||
//***************************************************************************
|
||||
/// The type used for ids.
|
||||
//***************************************************************************
|
||||
typedef uint_least8_t type_id_t;
|
||||
|
||||
//***************************************************************************
|
||||
/// The id a unsupported types.
|
||||
//***************************************************************************
|
||||
static const type_id_t UNSUPPORTED_TYPE_ID = integral_limits<type_id_t>::max;
|
||||
|
||||
private:
|
||||
|
||||
// All types of variant are friends.
|
||||
@ -133,16 +145,6 @@ namespace etl
|
||||
//***************************************************************************
|
||||
static const size_t ALIGNMENT = etl::largest_alignment<T1, T2, T3, T4, T5, T6, T7, T8>::value;
|
||||
|
||||
//***************************************************************************
|
||||
/// The type used for ids.
|
||||
//***************************************************************************
|
||||
typedef uint_least8_t type_id_t;
|
||||
|
||||
//***************************************************************************
|
||||
/// The id a unsupported types.
|
||||
//***************************************************************************
|
||||
static const type_id_t UNSUPPORTED_TYPE_ID = integral_limits<type_id_t>::max;
|
||||
|
||||
//***************************************************************************
|
||||
/// Short form of no_type placeholders.
|
||||
//***************************************************************************
|
||||
@ -701,6 +703,84 @@ namespace etl
|
||||
type_id = other.type_id;
|
||||
}
|
||||
|
||||
#if !ETL_CPP11_SUPPORTED
|
||||
//***************************************************************************
|
||||
/// Emplace with one constructor parameter.
|
||||
//***************************************************************************
|
||||
template <typename T, typename TP1>
|
||||
T& emplace(const TP1& value1)
|
||||
{
|
||||
STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
|
||||
|
||||
destruct_current();
|
||||
::new (static_cast<T*>(data)) T(value1);
|
||||
type_id = Type_Id_Lookup<T>::type_id;
|
||||
|
||||
return *static_cast<T*>(data);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Emplace with two constructor parameters.
|
||||
//***************************************************************************
|
||||
template <typename T, typename TP1, typename TP2>
|
||||
T& emplace(const TP1& value1, const TP2& value2)
|
||||
{
|
||||
STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
|
||||
|
||||
destruct_current();
|
||||
::new (static_cast<T*>(data)) T(value1, value2);
|
||||
type_id = Type_Id_Lookup<T>::type_id;
|
||||
|
||||
return *static_cast<T*>(data);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Emplace with three constructor parameters.
|
||||
//***************************************************************************
|
||||
template <typename T, typename TP1, typename TP2, typename TP3>
|
||||
T& emplace(const TP1& value1, const TP2& value2, const TP3& value3)
|
||||
{
|
||||
STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
|
||||
|
||||
destruct_current();
|
||||
::new (static_cast<T*>(data)) T(value1, value2, value3);
|
||||
type_id = Type_Id_Lookup<T>::type_id;
|
||||
|
||||
return *static_cast<T*>(data);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Emplace with four constructor parameters.
|
||||
//***************************************************************************
|
||||
template <typename T, typename TP1, typename TP2, typename TP3, typename TP4>
|
||||
T& emplace(const TP1& value1, const TP2& value2, const TP3& value3, const TP4& value4)
|
||||
{
|
||||
STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
|
||||
|
||||
destruct_current();
|
||||
::new (static_cast<T*>(data)) T(value1, value2, value3, value4);
|
||||
type_id = Type_Id_Lookup<T>::type_id;
|
||||
|
||||
return *static_cast<T*>(data);
|
||||
}
|
||||
|
||||
#else
|
||||
//*************************************************************************
|
||||
/// Emplace with variadic constructor parameters.
|
||||
//*************************************************************************
|
||||
template <typename T, typename... Args>
|
||||
T& emplace(Args&&... args)
|
||||
{
|
||||
STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
|
||||
|
||||
destruct_current();
|
||||
::new (static_cast<T*>(data)) T(std::forward<Args>(args)...);
|
||||
type_id = Type_Id_Lookup<T>::type_id;
|
||||
|
||||
return *static_cast<T*>(data);
|
||||
}
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// Assignment operator for T1 type.
|
||||
///\param value The value to assign.
|
||||
@ -821,6 +901,14 @@ namespace etl
|
||||
return type_id == Type_Id_Lookup<T>::type_id;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Gets the index of the type currently stored or UNSUPPORTED_TYPE_ID
|
||||
//***************************************************************************
|
||||
ETL_CONSTEXPR size_t index() const
|
||||
{
|
||||
return type_id;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Clears the value to 'no valid stored value'.
|
||||
//***************************************************************************
|
||||
|
||||
@ -1,3 +1,7 @@
|
||||
===============================================================================
|
||||
10.17.0
|
||||
Added emplace functions to etl::variant.
|
||||
|
||||
===============================================================================
|
||||
10.16.1
|
||||
Improved performance of emplace for value_type parameters.
|
||||
|
||||
@ -34,6 +34,7 @@ SOFTWARE.
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -99,6 +100,128 @@ namespace
|
||||
// This line should compile with no errors.
|
||||
test_variant_max_types variant_max;
|
||||
|
||||
struct D1
|
||||
{
|
||||
D1(const std::string& a_)
|
||||
: a(a_)
|
||||
{
|
||||
}
|
||||
|
||||
std::string a;
|
||||
};
|
||||
|
||||
struct D2
|
||||
{
|
||||
D2(const std::string& a_, const std::string& b_)
|
||||
: a(a_),
|
||||
b(b_)
|
||||
{
|
||||
}
|
||||
|
||||
std::string a;
|
||||
std::string b;
|
||||
};
|
||||
|
||||
struct D3
|
||||
{
|
||||
D3(const std::string& a_, const std::string& b_, const std::string& c_)
|
||||
: a(a_),
|
||||
b(b_),
|
||||
c(c_)
|
||||
{
|
||||
}
|
||||
|
||||
std::string a;
|
||||
std::string b;
|
||||
std::string c;
|
||||
};
|
||||
|
||||
struct D4
|
||||
{
|
||||
D4(const std::string& a_, const std::string& b_, const std::string& c_, const std::string& d_)
|
||||
: a(a_),
|
||||
b(b_),
|
||||
c(c_),
|
||||
d(d_)
|
||||
{
|
||||
}
|
||||
|
||||
std::string a;
|
||||
std::string b;
|
||||
std::string c;
|
||||
std::string d;
|
||||
};
|
||||
|
||||
bool operator == (const D1& lhs, const D1& rhs)
|
||||
{
|
||||
return (lhs.a == rhs.a);
|
||||
}
|
||||
|
||||
bool operator == (const D2& lhs, const D2& rhs)
|
||||
{
|
||||
return (lhs.a == rhs.a) && (lhs.b == rhs.b);
|
||||
}
|
||||
|
||||
bool operator == (const D3& lhs, const D3& rhs)
|
||||
{
|
||||
return (lhs.a == rhs.a) && (lhs.b == rhs.b) && (lhs.c == rhs.c);
|
||||
}
|
||||
|
||||
bool operator == (const D4& lhs, const D4& rhs)
|
||||
{
|
||||
return (lhs.a == rhs.a) && (lhs.b == rhs.b) && (lhs.c == rhs.c) && (lhs.d == rhs.d);
|
||||
}
|
||||
|
||||
bool operator != (const D1& lhs, const D1& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
bool operator != (const D2& lhs, const D2& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
bool operator != (const D3& lhs, const D3& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
bool operator != (const D4& lhs, const D4& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
std::ostream& operator <<(std::ostream& os, const D1& d1)
|
||||
{
|
||||
os << d1.a;
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator <<(std::ostream& os, const D2& d2)
|
||||
{
|
||||
os << d2.a << " " << d2.b;
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator <<(std::ostream& os, const D3& d3)
|
||||
{
|
||||
os << d3.a << " " << d3.b << " " << d3.c;
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator <<(std::ostream& os, const D4& d4)
|
||||
{
|
||||
os << d4.a << " " << d4.b << " " << d4.c << " " << d4.d;
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
typedef etl::variant<D1, D2, D3, D4> test_variant_emplace;
|
||||
|
||||
SUITE(test_variant)
|
||||
{
|
||||
TEST(test_alignment)
|
||||
@ -666,5 +789,27 @@ namespace
|
||||
variant.upcast<base>().set();
|
||||
CHECK_EQUAL(2, variant.get<derived_2>().value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(TestEmplace)
|
||||
{
|
||||
test_variant_emplace variant;
|
||||
|
||||
variant.emplace<D1>("1");
|
||||
CHECK(variant.is_type<D1>());
|
||||
CHECK_EQUAL(D1("1"), variant.get<D1>());
|
||||
|
||||
variant.emplace<D2>("1", "2");
|
||||
CHECK(variant.is_type<D2>());
|
||||
CHECK_EQUAL(D2("1", "2"), variant.get<D2>());
|
||||
|
||||
variant.emplace<D3>("1", "2", "3");
|
||||
CHECK(variant.is_type<D3>());
|
||||
CHECK_EQUAL(D3("1", "2", "3"), variant.get<D3>());
|
||||
|
||||
variant.emplace<D4>("1", "2", "3", "4");
|
||||
CHECK(variant.is_type<D4>());
|
||||
CHECK_EQUAL(D4("1", "2", "3", "4"), variant.get<D4>());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user