Core: Upp::Tuple C++17 structured binding support

This commit is contained in:
Mirek Fidler 2024-08-23 12:52:43 +02:00
parent 3638778b2e
commit d82ecd45eb
4 changed files with 124 additions and 2 deletions

View file

@ -0,0 +1,16 @@
* C:\upp\out\Core2024_autotest\CLANGx64.Debug.Debug_Full\Moveable.exe 23.08.2024 11:33:48, user: cxl
h = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
h = [0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
h = [0, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19]
h = [0, 4, 21, 22, 23, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19]
h = [0, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19]
=======================
h = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
h = [0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
h = [0, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19]
h = [0, 4, 21, 22, 23, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19]
h = [0, 4, 21, 22, 23, 21, 22, 23, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19]
h = [0, 4, 21, 22, 23, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19]
x = [one, two, three]
x.Find("two") = 1

View file

@ -0,0 +1,66 @@
#include <Core/Core.h>
using namespace Upp;
namespace Upp {
//template <>
//inline constexpr bool is_upp_guest<std::string> = true;
};
template <>
inline constexpr bool Upp::is_upp_guest<std::string> = true;
template<> inline hash_t Upp::GetHashValue(const std::string& a)
{
return memhash(a.data(), a.length());
}
CONSOLE_APP_MAIN
{
{
Vector<String> h;
for(int i = 0; i < 20; i++)
h << AsString(i);
RDUMP(h);
Vector<int> rem = { 1, 2, 3 };
h.Remove(rem);
RDUMP(h);
h.RemoveIf([&](int i) { return h[i].EndsWith("8"); });
RDUMP(h);
Vector<String> n = { "21", "22", "23" };
h.Insert(2, pick(n));
RDUMP(h);
h.Remove(2, 3);
RDUMP(h);
}
RLOG("=======================");
{
Vector<std::string> h;
for(int i = 0; i < 20; i++)
h << AsString(i).ToStd();
RDUMP(h);
Vector<int> rem = { 1, 2, 3 };
h.Remove(rem);
RDUMP(h);
h.RemoveIf([&](int i) { return h[i].back() == '8'; });
RDUMP(h);
Vector<std::string> n = { "21", "22", "23" };
h.Insert(2, n);
RDUMP(h);
h.Insert(2, pick(n));
RDUMP(h);
h.Remove(2, 3);
RDUMP(h);
}
{
Index<std::string> x { "one", "two", "three" };
RDUMP(x);
RDUMP(x.Find("two"));
}
CheckLogEtalon();
}

View file

@ -0,0 +1,10 @@
uses
Core;
file
Etalon.log,
Moveable.cpp;
mainconfig
"" = "";

View file

@ -14,6 +14,8 @@ template <typename A>
struct TupleN<1, A>
{
A a;
using T1 = A;
bool operator==(const TupleN& x) const { return a == x.a; }
int Compare(const TupleN& x) const { return SgnCompare(a, x.a); }
@ -56,6 +58,8 @@ template <typename A, typename B>
struct TupleN<2, A, B> : public TupleN<1, A> {
typedef TupleN<1, A> Base;
B b;
using T2 = B;
TUPLE_N_METHODS(b, 1);
@ -71,6 +75,8 @@ struct TupleN<3, A, B, C> : public TupleN<2, A, B>
typedef TupleN<2, A, B> Base;
C c;
using T3 = C;
TUPLE_N_METHODS(c, 2);
TupleN(const A& a, const B& b, const C& c) : Base(a, b), c(c) {}
@ -85,6 +91,8 @@ struct TupleN<4, A, B, C, D> : public TupleN<3, A, B, C>
typedef TupleN<3, A, B, C> Base;
D d;
using T4 = D;
TUPLE_N_METHODS(d, 3);
TupleN(const A& a, const B& b, const C& c, const D& d) : Base(a, b, c), d(d) {}
@ -118,13 +126,16 @@ struct Tuple : public TupleN<sizeof...(Args), Args...> {
private:
typedef TupleN<sizeof...(Args), Args...> Base;
friend void AssertMoveable0(Tuple *) {}
public:
template <int I>
const auto& Get() const { return GetFromTuple(*this, IndexI__<I>()); }
template <int I>
auto& Get() { return GetFromTuple(*this, IndexI__<I>()); }
template <int I> // std compatibility & C++17 structured binding support
const auto& get() const { return GetFromTuple(*this, IndexI__<I>()); }
template <int I> // std compatibility & C++17 structured binding support
auto& get() { return GetFromTuple(*this, IndexI__<I>()); }
template <typename T> const T& Get() const { return GetFromTupleByType(*this, (T*)NULL); }
template <typename T> T& Get() { return GetFromTupleByType(*this, (T*)NULL); }
@ -227,6 +238,25 @@ struct Tie4 {
template <typename A, typename B, typename C, typename D>
Tie4<A, B, C, D> Tie(A& a, B& b, C& c, D& d) { return Tie4<A, B, C, D>(a, b, c, d); }
}; // end Upp namespace
template<typename... Args>
struct std::tuple_element<0, Upp::Tuple<Args...>> { using type = typename Upp::Tuple<Args...>::T1; };
template<typename... Args>
struct std::tuple_element<1, Upp::Tuple<Args...>> { using type = typename Upp::Tuple<Args...>::T2; };
template<typename... Args>
struct std::tuple_element<2, Upp::Tuple<Args...>> { using type = typename Upp::Tuple<Args...>::T3; };
template<typename... Args>
struct std::tuple_element<3, Upp::Tuple<Args...>> { using type = typename Upp::Tuple<Args...>::T4; };
template<typename... Args>
struct std::tuple_size<Upp::Tuple<Args...>> { static const int value = sizeof...(Args); };
namespace Upp {
// Backward compatibility
template <typename A, typename B> using Tuple2 = Tuple<A, B>;