mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
Core: Upp::Tuple C++17 structured binding support
This commit is contained in:
parent
3638778b2e
commit
d82ecd45eb
4 changed files with 124 additions and 2 deletions
16
autotest/Moveable/Etalon.log
Normal file
16
autotest/Moveable/Etalon.log
Normal 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
|
||||
66
autotest/Moveable/Moveable.cpp
Normal file
66
autotest/Moveable/Moveable.cpp
Normal 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();
|
||||
}
|
||||
10
autotest/Moveable/Moveable.upp
Normal file
10
autotest/Moveable/Moveable.upp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
uses
|
||||
Core;
|
||||
|
||||
file
|
||||
Etalon.log,
|
||||
Moveable.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "";
|
||||
|
||||
|
|
@ -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>;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue