00001 #ifndef LIBGEODECOMP_STORAGE_SELECTOR_H
00002 #define LIBGEODECOMP_STORAGE_SELECTOR_H
00003
00004 #include <libgeodecomp/config.h>
00005 #include <libgeodecomp/io/logger.h>
00006 #include <libgeodecomp/misc/apitraits.h>
00007 #include <libgeodecomp/storage/defaultfilter.h>
00008 #include <libgeodecomp/storage/filterbase.h>
00009 #include <libflatarray/flat_array.hpp>
00010 #include <typeinfo>
00011
00012 #ifdef LIBGEODECOMP_WITH_SILO
00013 #include <silo.h>
00014 #endif
00015
00016 #ifdef LIBGEODECOMP_WITH_MPI
00017 #include <libgeodecomp/communication/typemaps.h>
00018 #endif
00019
00020 namespace LibGeoDecomp {
00021
00022 class APITraits;
00023
00024 namespace SelectorHelpers {
00025
00026 template<typename CELL, typename MEMBER>
00027 class GetMemberOffset
00028 {
00029 public:
00030 int operator()(MEMBER CELL:: *memberPointer, APITraits::TrueType)
00031 {
00032 return LibFlatArray::member_ptr_to_offset()(memberPointer);
00033 }
00034
00035 int operator()(MEMBER CELL:: *memberPointer, APITraits::FalseType)
00036 {
00037 return -1;
00038 }
00039 };
00040
00046 template<typename CELL>
00047 class PrimitiveSelector
00048 {
00049 public:
00050 template<typename MEMBER>
00051 void operator()(const CELL *source, MEMBER *target, const std::size_t length) const
00052 {
00053 std::copy(source, source + length, target);
00054 }
00055
00056 const std::string name() const
00057 {
00058 return "primitiveType";
00059 }
00060
00061 std::size_t sizeOfMember() const
00062 {
00063 return sizeof(CELL);
00064 }
00065
00066 std::size_t sizeOfExternal() const
00067 {
00068 return sizeof(CELL);
00069 }
00070
00071 int offset() const
00072 {
00073 return 0;
00074 }
00075
00076 void copyMemberIn(const char *source, CELL *target, int num) const
00077 {
00078 const CELL *actualSource = reinterpret_cast<const CELL*>(source);
00079 std::copy(actualSource, actualSource + num, target);
00080 }
00081
00082 void copyMemberOut(const CELL *source, char *target, int num) const
00083 {
00084 CELL *actualTarget = reinterpret_cast<CELL*>(target);
00085 std::copy(source, source + num, actualTarget);
00086 }
00087
00088
00089
00090
00091 };
00092
00093 }
00094
00105 template<typename CELL>
00106 class Selector
00107 {
00108 public:
00109 Selector() :
00110 memberPointer(0),
00111 memberSize(0),
00112 externalSize(0),
00113 memberOffset(0),
00114 memberName("memberName not initialized")
00115 {}
00116
00117 template<typename MEMBER>
00118 Selector(
00119 MEMBER CELL:: *memberPointer,
00120 const std::string& memberName) :
00121 memberPointer(reinterpret_cast<char CELL::*>(memberPointer)),
00122 memberSize(sizeof(MEMBER)),
00123 externalSize(sizeof(MEMBER)),
00124 memberOffset(typename SelectorHelpers::GetMemberOffset<CELL, MEMBER>()(
00125 memberPointer,
00126 typename APITraits::SelectSoA<CELL>::Value())),
00127 memberName(memberName),
00128 filter(new DefaultFilter<CELL, MEMBER, MEMBER>)
00129 {}
00130
00131 template<typename MEMBER>
00132 Selector(
00133 MEMBER CELL:: *memberPointer,
00134 const std::string& memberName,
00135 const boost::shared_ptr<FilterBase<CELL> >& filter) :
00136 memberPointer(reinterpret_cast<char CELL::*>(memberPointer)),
00137 memberSize(sizeof(MEMBER)),
00138 externalSize(filter->sizeOf()),
00139 memberOffset(typename SelectorHelpers::GetMemberOffset<CELL, MEMBER>()(
00140 memberPointer,
00141 typename APITraits::SelectSoA<CELL>::Value())),
00142 memberName(memberName),
00143 filter(filter)
00144 {}
00145
00146 inline const std::string& name() const
00147 {
00148 return memberName;
00149 }
00150
00151 inline std::size_t sizeOfMember() const
00152 {
00153 return memberSize;
00154 }
00155
00156 inline std::size_t sizeOfExternal() const
00157 {
00158 return externalSize;
00159 }
00160
00161 template<typename MEMBER>
00162 inline bool checkTypeID() const
00163 {
00164 return filter->checkExternalTypeID(typeid(MEMBER));
00165 }
00166
00170 inline int offset() const
00171 {
00172 return memberOffset;
00173 }
00174
00179 inline void copyMemberIn(const char *source, CELL *target, int num) const
00180 {
00181 filter->copyMemberIn(source, target, num, memberPointer);
00182 }
00183
00188 inline void copyMemberOut(const CELL *source, char *target, int num) const
00189 {
00190 filter->copyMemberOut(source, target, num, memberPointer);
00191 }
00192
00197 inline void copyStreakIn(const char *first, const char *last, char *target) const
00198 {
00199 filter->copyStreakIn(first, last, target);
00200 }
00201
00206 inline void copyStreakOut(const char *first, const char *last, char *target) const
00207 {
00208 filter->copyStreakOut(first, last, target);
00209 }
00210
00211 #ifdef LIBGEODECOMP_WITH_SILO
00212 int siloTypeID() const
00213 {
00214 return filter->siloTypeID();
00215 }
00216 #endif
00217
00218 #ifdef LIBGEODECOMP_WITH_MPI
00219 MPI_Datatype mpiDatatype() const
00220 {
00221 return filter->mpiDatatype();
00222 }
00223 #endif
00224
00225 std::string typeName() const
00226 {
00227 return filter->typeName();
00228 }
00229
00230 int arity() const
00231 {
00232 return filter->arity();
00233 }
00234
00235 template<class ARCHIVE>
00236 void serialize(ARCHIVE& archive, const unsigned int version)
00237 {
00238 std::size_t *buf =
00239 reinterpret_cast<std::size_t*>(
00240 const_cast<char CELL::**>(&memberPointer));
00241 archive & *buf;
00242
00243 archive & memberSize;
00244 archive & externalSize;
00245 archive & memberOffset;
00246 archive & memberName;
00247 archive & filter;
00248 }
00249
00250 private:
00251 char CELL:: *memberPointer;
00252 std::size_t memberSize;
00253 std::size_t externalSize;
00254 int memberOffset;
00255 std::string memberName;
00256 boost::shared_ptr<FilterBase<CELL> > filter;
00257 };
00258
00263 template<>
00264 class Selector<char> : public SelectorHelpers::PrimitiveSelector<char>
00265 {
00266 };
00267
00268 template<>
00269 class Selector<int> : public SelectorHelpers::PrimitiveSelector<int>
00270 {
00271 };
00272
00273 template<>
00274 class Selector<unsigned> : public SelectorHelpers::PrimitiveSelector<unsigned>
00275 {
00276 };
00277
00278 template<>
00279 class Selector<float> : public SelectorHelpers::PrimitiveSelector<float>
00280 {
00281 };
00282
00283 template<>
00284 class Selector<double> : public SelectorHelpers::PrimitiveSelector<double>
00285 {
00286 };
00287
00288 }
00289
00290 #endif