Home » U++ Library support » U++ Core » NEW: generic Toupel grouper
Re: NEW: generic Toupel grouper [message #28129 is a reply to message #28128] |
Tue, 17 August 2010 22:52 |
|
kohait00 wrote on Tue, 17 August 2010 22:22 |
Quote: | Don't forget about the GetCount()
| i dont think that it is that much of use either. becasue everything is know at compiletime, and Tupel is not meant to be a base class. so i cant imagine any practicle usecase. i'd prefer to, as mirek statet, have it as simple as possible, and serve its due as beeing a compile time known simple strong type container / grouper of data types. not more nor less, except there is more things to have on it, that are of real use.
|
The main reason I want GetCount() is that it is in every container, from Vector to String. You are right that everything is known at compile time, but it doesn't really mean that you know everything when you write some code E.g.: Sometimes there are situations where you create templated function which iterates through a container. It doesn't even have to be you who uses the code in the end.
One of the reasons why I like U++ so much is its consistency of interfaces. I feel safe to write template or macro that is doing something general with only basic assumptions about interface, often without knowing what some crazy user of my code will send to it And it is not only about iterating in containers - also ToString (DUMP and LOG are great example of what I tried to describe in previous paragraph), Serialize, Null constructors, operator<<= etc.
Honza
|
|
|
|
Re: NEW: generic Toupel grouper [message #28133 is a reply to message #28131] |
Tue, 17 August 2010 23:53 |
|
I would useint GetCount() const
{
if(typeid(T5) != typeid(Nuller)) return 5;
if(typeid(T4) != typeid(Nuller)) return 4;
if(typeid(T3) != typeid(Nuller)) return 3;
return 2;
}
That works even for the dumb user
Honza
|
|
|
|
Re: NEW: generic Toupel grouper [message #28365 is a reply to message #28152] |
Mon, 30 August 2010 20:57 |
|
mirek
Messages: 13979 Registered: November 2005
|
Ultimate Member |
|
|
kohait00 wrote on Thu, 19 August 2010 02:30 | thats way better. one would need to check for intermediate Nuller though anyway, beeing that the case, why not simply do this
inline int GetCount() const { return 5; }
so it's up to mirek to decide what happens with this stuff
|
I believe it is not very helpful to mix Tuples with Value or try to pretend they are maps. In fact, ValueArray covers such usage pretty well IMO.
I believe that the common usage scenario is in cases where you need "quick" struct which is not worth defining, like
static Tuple<int, const char *> mapping[] = {
0, "foo",
1, "bar"
}
In fact, the only think to resolve is how to name its members.
Right now, "a, b, c, d, e..." sound like the best option. STL templated indexing seems overengineered to me, "first, second, third..." are too long and "v0, v1, v2, v3..." have "zero index issue".
Well, maybe something like "key, value, value1, value2" would reflect the most typical use.
More ideas? Or letters are it?
|
|
|
|
Re: NEW: generic Toupel grouper [message #28367 is a reply to message #27972] |
Mon, 30 August 2010 23:13 |
|
I agree with the a,b,c,d,e... too. It is nice and simple and fast to write. One more question is how many values should be supported. I personally think that a-f should be about enough...
Honza
|
|
|
Re: NEW: generic Toupel grouper [message #28369 is a reply to message #28367] |
Tue, 31 August 2010 08:31 |
|
kohait00
Messages: 939 Registered: July 2009 Location: Germany
|
Experienced Contributor |
|
|
if more is needed, this should be possible..
Tupel<int,float,int,float,Tupel<String,char,String,char,double> >
in terms of Tupel as container: Tupel is actually no container..here mirek is right.its a grouper class. anyway, in case such a behaviour is needed, it can be subsequently added deriving.
|
|
|
Re: NEW: generic Toupel grouper [message #28370 is a reply to message #28369] |
Tue, 31 August 2010 08:44 |
|
kohait00
Messages: 939 Registered: July 2009 Location: Germany
|
Experienced Contributor |
|
|
so here is a cleaned up proposal..
template<class T1, class T2, class T3=EmptyClass, class T4=EmptyClass, class T5=EmptyClass>
class Tupel {
public:
Tupel(const T1 & a, const T2 & b, const T3 & c, const T4 & d, const T5 & e)
: a(a), b(b), c(c), d(d), e(e) {}
Tupel() {}
T1 a; T2 b; T3 c; T4 d; T5 e;
};
|
|
|
|
|
Re: NEW: generic Toupel grouper [message #28378 is a reply to message #28367] |
Tue, 31 August 2010 13:29 |
|
mirek
Messages: 13979 Registered: November 2005
|
Ultimate Member |
|
|
dolik.rce wrote on Mon, 30 August 2010 17:13 | I agree with the a,b,c,d,e... too. It is nice and simple and fast to write. One more question is how many values should be supported. I personally think that a-f should be about enough...
Honza
|
IMO, 4 is more than enough....
Here is what I got after bit of experimenting:
template <typename A, typename B>
struct Tuple2 {
union {
A a;
A key;
};
union {
B b;
B value;
};
int Compare(const Tuple2& x) const { return CombineCompare(a, x.a)(b, x.b); }
bool operator==(const Tuple2& x) const { return Compare(x) == 0; }
bool operator!=(const Tuple2& x) const { return Compare(x) != 0; }
bool operator<=(const Tuple2& x) const { return Compare(x) <= 0; }
bool operator>=(const Tuple2& x) const { return Compare(x) >= 0; }
bool operator<(const Tuple2& x) const { return Compare(x) != 0; }
bool operator>(const Tuple2& x) const { return Compare(x) != 0; }
unsigned GetHashValue() const { return CombineHash(a, b); }
};
template <typename A, typename B>
inline Tuple2<A, B> MakeTuple(const A& a, const B& b)
{
Tuple2<A, B> r;
r.a = a;
r.b = b;
return r;
}
template <typename A, typename B, typename C>
struct Tuple3 {
union {
A a;
A key;
};
union {
B b;
B value;
};
union {
C c;
C value1;
};
int Compare(const Tuple3& x) const { return CombineCompare(a, x.a)(b, x.b)(c, x.c); }
bool operator==(const Tuple3& x) const { return Compare(x) == 0; }
bool operator!=(const Tuple3& x) const { return Compare(x) != 0; }
bool operator<=(const Tuple3& x) const { return Compare(x) <= 0; }
bool operator>=(const Tuple3& x) const { return Compare(x) >= 0; }
bool operator<(const Tuple3& x) const { return Compare(x) != 0; }
bool operator>(const Tuple3& x) const { return Compare(x) != 0; }
unsigned GetHashValue() const { return CombineHash(a, b, c); }
};
template <typename A, typename B, typename C>
inline Tuple3<A, B, C> MakeTuple(const A& a, const B& b, const C& c)
{
Tuple3<A, B, C> r;
r.a = a;
r.b = b;
r.c = c;
return r;
}
template <typename A, typename B, typename C, typename D>
struct Tuple4 {
union {
A a;
A key;
};
union {
B b;
B value;
};
union {
C c;
C value1;
};
union {
D d;
D value2;
};
int Compare(const Tuple4& x) const { return CombineCompare(a, x.a)(b, x.b)(c, x.c)(d, x.d); }
bool operator==(const Tuple4& x) const { return Compare(x) == 0; }
bool operator!=(const Tuple4& x) const { return Compare(x) != 0; }
bool operator<=(const Tuple4& x) const { return Compare(x) <= 0; }
bool operator>=(const Tuple4& x) const { return Compare(x) >= 0; }
bool operator<(const Tuple4& x) const { return Compare(x) != 0; }
bool operator>(const Tuple4& x) const { return Compare(x) != 0; }
unsigned GetHashValue() const { return CombineHash(a, b, c, d); }
};
template <typename A, typename B, typename C, typename D>
inline Tuple4<A, B, C, D> MakeTuple(const A& a, const B& b, const C& c, const D& d)
{
Tuple4<A, B, C, D> r;
r.a = a;
r.b = b;
r.c = c;
r.d = d;
return r;
}
|
|
|
Re: NEW: generic Toupel grouper [message #28379 is a reply to message #28378] |
Tue, 31 August 2010 13:34 |
|
mirek
Messages: 13979 Registered: November 2005
|
Ultimate Member |
|
|
Upgrade:
template <typename A, typename B>
struct Tuple2 {
union {
A a;
A key;
};
union {
B b;
B value;
};
bool operator==(const Tuple2& x) const { return a == x.a && b == x.b; }
bool operator!=(const Tuple2& x) const { return !operator==(x); }
int Compare(const Tuple2& x) const { return CombineCompare(a, x.a)(b, x.b); }
bool operator<=(const Tuple2& x) const { return Compare(x) <= 0; }
bool operator>=(const Tuple2& x) const { return Compare(x) >= 0; }
bool operator<(const Tuple2& x) const { return Compare(x) != 0; }
bool operator>(const Tuple2& x) const { return Compare(x) != 0; }
unsigned GetHashValue() const { return CombineHash(a, b); }
};
template <typename A, typename B>
inline Tuple2<A, B> MakeTuple(const A& a, const B& b)
{
Tuple2<A, B> r;
r.a = a;
r.b = b;
return r;
}
template <typename A, typename B, typename C>
struct Tuple3 {
union {
A a;
A key;
};
union {
B b;
B value;
};
union {
C c;
C value1;
};
bool operator==(const Tuple3& x) const { return a == x.a && b == x.b && c == x.c; }
bool operator!=(const Tuple3& x) const { return !operator==(x); }
int Compare(const Tuple3& x) const { return CombineCompare(a, x.a)(b, x.b)(c, x.c); }
bool operator<=(const Tuple3& x) const { return Compare(x) <= 0; }
bool operator>=(const Tuple3& x) const { return Compare(x) >= 0; }
bool operator<(const Tuple3& x) const { return Compare(x) != 0; }
bool operator>(const Tuple3& x) const { return Compare(x) != 0; }
unsigned GetHashValue() const { return CombineHash(a, b, c); }
};
template <typename A, typename B, typename C>
inline Tuple3<A, B, C> MakeTuple(const A& a, const B& b, const C& c)
{
Tuple3<A, B, C> r;
r.a = a;
r.b = b;
r.c = c;
return r;
}
template <typename A, typename B, typename C, typename D>
struct Tuple4 {
union {
A a;
A key;
};
union {
B b;
B value;
};
union {
C c;
C value1;
};
union {
D d;
D value2;
};
bool operator==(const Tuple4& x) const { return a == x.a && b == x.b && c == x.c && d == x.d; }
bool operator!=(const Tuple4& x) const { return !operator==(x); }
int Compare(const Tuple4& x) const { return CombineCompare(a, x.a)(b, x.b)(c, x.c)(d, x.d); }
bool operator<=(const Tuple4& x) const { return Compare(x) <= 0; }
bool operator>=(const Tuple4& x) const { return Compare(x) >= 0; }
bool operator<(const Tuple4& x) const { return Compare(x) != 0; }
bool operator>(const Tuple4& x) const { return Compare(x) != 0; }
unsigned GetHashValue() const { return CombineHash(a, b, c, d); }
};
template <typename A, typename B, typename C, typename D>
inline Tuple4<A, B, C, D> MakeTuple(const A& a, const B& b, const C& c, const D& d)
{
Tuple4<A, B, C, D> r;
r.a = a;
r.b = b;
r.c = c;
r.d = d;
return r;
}
|
|
|
Re: NEW: generic Toupel grouper [message #28380 is a reply to message #28370] |
Tue, 31 August 2010 13:36 |
|
mirek
Messages: 13979 Registered: November 2005
|
Ultimate Member |
|
|
kohait00 wrote on Tue, 31 August 2010 02:44 | so here is a cleaned up proposal..
template<class T1, class T2, class T3=EmptyClass, class T4=EmptyClass, class T5=EmptyClass>
class Tupel {
public:
Tupel(const T1 & a, const T2 & b, const T3 & c, const T4 & d, const T5 & e)
: a(a), b(b), c(c), d(d), e(e) {}
Tupel() {}
T1 a; T2 b; T3 c; T4 d; T5 e;
};
|
There are two troubles:
- sizeof(EmptyClass) == 1, and all these members make it impossible to be initialized with braced list.
- with constructor, again it cannot be initialized with braced list (which, for me, is very important)
|
|
|
Re: NEW: generic Toupel grouper [message #28382 is a reply to message #28380] |
Tue, 31 August 2010 13:51 |
|
kohait00
Messages: 939 Registered: July 2009 Location: Germany
|
Experienced Contributor |
|
|
nice work,
btw: doensnt ==, !=, etc imply a quite a lot on class capabilities
EmptyClass: what about a DummyClass
class DummyClass
{
public:
DummyClass() {}
DummyClass(const DummyClass&) {}
};
it even could derive from EmptyClass to compare maybe
[Updated on: Tue, 31 August 2010 13:55] Report message to a moderator
|
|
|
Re: NEW: generic Toupel grouper [message #28386 is a reply to message #28382] |
Tue, 31 August 2010 14:04 |
|
kohait00
Messages: 939 Registered: July 2009 Location: Germany
|
Experienced Contributor |
|
|
void* is simple but makes things possible
template<class A, class B, class C=void*, class D=void*>
class Tupel {
public:
Tupel(const A& a, const B& b, const C& c = NULL, const D& d = NULL)
: a(a), b(b), c(c), d(d) {}
Tupel() {}
A a; B b; C c; D d;
};
EDIT: union is problematic, if T=One<int> i.e.
template<class A, class B, class C=void*, class D=void*>
class Tupel {
public:
Tupel(const A& a, const B& b, const C& c = NULL, const D& d = NULL)
: a(a), b(b), c(c), d(d) {}
Tupel() {}
union { A a, key, v1; };
union { B b, value, v2; };
union { C c, v3; };
union { D d, v4; };
};
Quote: |
error: member 'Upp::One<int> Tupel<int, Upp::One<int>, Upp::String, int>::<anonymous union>::b' with constructor not allowe
d in union
|
TDMGCC
[Updated on: Tue, 31 August 2010 14:09] Report message to a moderator
|
|
|
|
|
|
|
Goto Forum:
Current Time: Mon May 13 08:06:59 CEST 2024
Total time taken to generate the page: 0.03936 seconds
|