>> This looks like a design issue to me.
>> If exactly the first half is empty in a whole subclass of entities
>> You
>> use, maybe it is time to reorganize/redesign the code. Like this You
>> may avoid the tradeoff between speed and size.
> Okay, with my original post I was trying to avoid the actual details
> of my project. Obviously this didn't work, because even though you all
> bring up very good points, they don't really apply to my specific
> situation (I think). Thus, I will try again, now going into specific
> details.
So You were dissatisfied with the result of Your other thread "The
future of C++'s static language"?
The techiques proposed in that thread may fit here, too.
Secondly: I do not see You really gain much with
an approach which tries to save the wasted space,
because once the compiler knows that all objects
that interact with each other have the same size,
some rigid optimizations (automatic vectorization)
may apply.
Is size really a problem?
Then go into the shop and buy some additional 512MB chip.
I am not kidding. If I look at the development of
memory available in a standard PC during the last 10 years,
who cares about memory consumption tomorrow, when Your
program has left development state?
I still think that the best You can do is build
class multi_vector and plug it into
an expression template engine (use PETE or use mine).
--------------
But if You insist on saving space - here is my
brainstorm idea how to achieve it.
What I like most with this approach is the type saftey
for the components.
// This is only a sketch!
// This code will not compile and may have some errors in it.
// some demo TinyVector
template <size_t Size, class T>
struct TinyVector
{
double Data[Size];
// Some features missing here like
// operator()(size_t index)
Quote:};
// The Dummy that helps us to save some space
struct Empty
{}; // empty class optimization is available now
template <bool HasScalar,
bool HasPseudoScalar,
bool HasVector,
bool HasBiVector>
class MultiVector
{
public:
using Loki::Select; // download loki at sourceforge.net
// or use boost::mpl::if_ (if You prefer it)
typedef typename
Select<HasScalar, double, Empty>::Result ScalarType;
typedef typename
Select<HasPseudoScalar, double, Empty>::Result PseudoScalarType;
typedef typename
Select<HasVector, TinyVector<3, double>, Empty>::Result VectorType;
typedef typename
Select<HasBiVector, TinyVector<3, double>, Empty>::Result
BiVectorType;
private:
ScalarType Scalar_;
PseudoScalarType PseudoScalar_;
VectorType Vector_;
BiVectorType Bivector_;
public:
MultiVector(ScalarType Scalar,
PseudoScalarType PseudoScalar,
VectorType Vector,
BiVectorType Bivector)
:
Scalar_(Scalar),
PseudoScalar_(PseudoScalar),
Vector_(Vector),
Bivector_(Bivector) {}
// MultiVector() {} // I dislike this one, because here You initialize
// // all data with 0 first
inline void setVector(double d1, double d2, double d3)
{
if (HasVector) // known at compile time => optimizer is happy
{
Vector_[1] = d1;
Vector_[2] = d2;
Vector_[3] = d3;
}
else
{
// runtime error
}
};
inline VectorType getVector() {
COMPILE_TIME_ASSERT(!SAME_TYPE(VectorType, Empty));
return Vector_;
}
inline void SetBiVector(double d1, double d2, double d3);
// etc;
Quote:};
////////////////////////////////////////////////////////////////////////
////
// operator+
template <class C> C operator+(const Empty& E, const C& c)
{
return c;
Quote:}
template <class C> C operator+(const C& c, const Empty& E)
{
return c;
Quote:}
// somehwre else
template <size_t Size, class T>
operator+(const TinyVector<Size, T>& V1, const TinyVector<Size, T>& V2);
template <bool LHS_HasScalar,
bool LHS_HasPseudoScalar,
bool LHS_HasVector,
bool LHS_HasBiVector,
bool RHS_HasScalar,
bool RHS_HasPseudoScalar,
bool RHS_HasVector,
bool RHS_HasBiVector>
MultiVector<
LHS_HasScalar || RHS_HasScalar,
LHS_HasPseudoScalar || RHS_HasPseudoScalar,
LHS_HasVector || RHS_HasVector,
LHS_HasBiVector || RHS_HasBiVector
>
operator+
(const MultiVector<LHS_HasScalar
LHS_HasPseudoScalar
LHS_HasVector
LHS_HasBiVector>& lhs,
const MultiVector<RHS_HasScalar
RHS_HasPseudoScalar
RHS_HasVector
RHS_HasBiVector>& rhs)
{
return MultiVector
<
LHS_HasScalar || RHS_HasScalar,
LHS_HasPseudoScalar || RHS_HasPseudoScalar,
LHS_HasVector || RHS_HasVector,
LHS_HasBiVector || RHS_HasBiVector
>
(
lhs.getScalar() + rhs.getScalar(),
//etc.
);
Quote:}
int main()
{
MultiVector<true, false, false, true>
MV1(5.0, Empty(), Empty(), TinyVector<3, double>(1.2, 3.4, 5.0));
MultiVector<true, false, false, false>
MV2(5.0, Empty(), Empty(), Empty());
// this here still is without an expression template engine,
// but that is pluggable afterwards :-)
MultiVector<true, false, false, true> MV3 = MV1 + MV2;
Quote:}
[ about comp.lang.c++.moderated. First time posters: do this! ]