00001
00025 #ifndef GALOIS_LAZYOBJECT_H
00026 #define GALOIS_LAZYOBJECT_H
00027
00028 #include "Galois/config.h"
00029 #include "Galois/Runtime/ll/gio.h"
00030 #include "Galois/TypeTraits.h"
00031
00032
00033 #include <boost/type_traits/has_trivial_constructor.hpp>
00034
00035 #include GALOIS_CXX11_STD_HEADER(type_traits)
00036 #include GALOIS_CXX11_STD_HEADER(utility)
00037
00038 namespace Galois {
00039
00045 template<typename T>
00046 class StrictObject {
00047 T data;
00048 public:
00049 typedef T value_type;
00050 typedef T& reference;
00051 typedef const T& const_reference;
00052 const static bool has_value = true;
00053
00054 StrictObject() { }
00055 StrictObject(const_reference t): data(t) { }
00056 const_reference get() const { return data; }
00057 reference get() { return data; }
00058 };
00059
00060 template<>
00061 struct StrictObject<void> {
00062 typedef void* value_type;
00063 typedef void* reference;
00064 typedef void* const_reference;
00065 const static bool has_value = false;
00066
00067 StrictObject() { }
00068 StrictObject(const_reference) { }
00069 reference get() const { return 0; }
00070 };
00071
00072 #if defined(__IBMCPP__) && __IBMCPP__ <= 1210
00073 namespace LazyObjectDetail {
00074
00075 template<typename T, typename CharData, bool>
00076 struct SafeDataBase {
00077 union type {
00078 CharData buf;
00079 T value_;
00080 T& value() { return value_; }
00081 const T& value() const { return value_; }
00082 };
00083 };
00084
00085 template<typename T, typename CharData>
00086 struct SafeDataBase<T, CharData, false> {
00087 union type {
00088 CharData buf;
00089 T& value() { return *reinterpret_cast<T*>(&buf); }
00090 const T& value() const { return *reinterpret_cast<const T*>(&buf); }
00091
00092 type() {
00093
00094
00095 }
00096 };
00097 };
00098
00103 template<typename T, typename CharData>
00104 struct SafeData: public SafeDataBase<T, CharData,
00105 boost::has_trivial_constructor<T>::value || Galois::has_known_trivial_constructor<T>::value > { };
00106
00107 }
00108 #endif
00109
00116 template<typename T>
00117 class LazyObject {
00118 typedef typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type CharData;
00119
00120 #if defined(__IBMCPP__) && __IBMCPP__ <= 1210
00121 typedef typename LazyObjectDetail::SafeData<T, CharData>::type Data;
00122 #else
00123 union Data {
00124 CharData buf;
00125 T value_;
00126
00127 Data() { }
00128 ~Data() { }
00129
00130 T& value() { return value_; }
00131 const T& value() const { return value_; }
00132 };
00133 #endif
00134
00135 Data data_;
00136
00137 T* cast() { return &data_.value(); }
00138 const T* cast() const { return &data_.value(); }
00139
00140 public:
00141 typedef T value_type;
00142 typedef T& reference;
00143 typedef const T& const_reference;
00144 const static bool has_value = true;
00145
00146
00147 struct size_of {
00148 const static size_t value = sizeof(T);
00149 };
00150
00151 void destroy() { cast()->~T(); }
00152 void construct(const_reference x) { new (cast()) T(x); }
00153
00154 template<typename... Args>
00155 void construct(Args&&... args) { new (cast()) T(std::forward<Args>(args)...); }
00156
00157 const_reference get() const { return *cast(); }
00158 reference get() { return *cast(); }
00159 };
00160
00161 template<>
00162 struct LazyObject<void> {
00163 typedef void* value_type;
00164 typedef void* reference;
00165 typedef void* const_reference;
00166 const static bool has_value = false;
00167 struct size_of {
00168 const static size_t value = 0;
00169 };
00170
00171 void destroy() { }
00172 void construct(const_reference x) { }
00173
00174 template<typename... Args>
00175 void construct(Args&&... args) { }
00176
00177 const_reference get() const { return 0; }
00178 };
00179
00180 }
00181 #endif