00001
00002
00003 #ifndef _BCP_VECTOR_CHANGE_H
00004 #define _BCP_VECTOR_CHANGE_H
00005
00006
00007
00008 #include "CoinHelperFunctions.hpp"
00009 #include "BCP_enum.hpp"
00010 #include "BCP_vector.hpp"
00011 #include "BCP_buffer.hpp"
00012
00020 template <class T> class BCP_vec_change {
00021 private:
00023 BCP_storage_t _storage;
00026 BCP_vec<int> _del_pos;
00030 BCP_vec<int> _change_pos;
00034 BCP_vec<T> _values;
00035
00036 public:
00043 BCP_vec_change(const BCP_storage_t st) : _storage(st) {}
00044
00047 BCP_vec_change(const T* first, const T* last) :
00048 _storage(BCP_Storage_Explicit) {
00049 _values.append(first, last);
00050 }
00051
00059 BCP_vec_change(const BCP_vec_change<T>& old_vec,
00060 const BCP_vec_change<T>& new_vec,
00061 const BCP_vec<int>& del_pos) :
00062 _storage(BCP_Storage_WrtParent), _del_pos(del_pos) {
00063 const BCP_vec<T>& ov = old_vec.explicit_vector();
00064 const BCP_vec<T>& nv = new_vec.explicit_vector();
00065 const int new_size = nv.size();
00066 const int old_size = ov.size();
00067 const int del_size = del_pos.size();
00068 int i, j, k;
00069 for (i = 0, j = 0, k = 0; i < old_size && k < del_size; ++i) {
00070 if (del_pos[k] == i) {
00071 ++k;
00072 continue;
00073 }
00074 if (ov[i] != nv[j]) {
00075 _change_pos.push_back(j);
00076 }
00077 ++j;
00078 }
00079 if (old_size - i > new_size - j)
00080 throw BCP_fatal_error("BCP_vec_change::BCP_vec_change() : \n \
00081 old_vec has entries not in new_vec but not listed in del_pos.\n");
00082 for ( ; i < old_size; ++i, ++j) {
00083 if (ov[i] != nv[j]) {
00084 _change_pos.push_back(j);
00085 }
00086 }
00087 const int change_size = _change_pos.size();
00088 _values.reserve(change_size + new_size - j);
00089 for (i = 0; i < change_size; ++i) {
00090 _values.unchecked_push_back(nv[_change_pos[i]]);
00091 }
00092 _values.append(nv.entry(j), nv.end());
00093 }
00094
00100 BCP_vec_change(const BCP_vec_change<T>& old_vec,
00101 const BCP_vec_change<T>& new_vec,
00102 const BCP_vec<int>& del_pos, const double etol) :
00103 _storage(BCP_Storage_WrtParent), _del_pos(del_pos) {
00104 const BCP_vec<T>& ov = old_vec.explicit_vector();
00105 const BCP_vec<T>& nv = new_vec.explicit_vector();
00106 const int new_size = nv.size();
00107 const int old_size = ov.size();
00108 const int del_size = del_pos.size();
00109 int i, j, k;
00110 for (i = 0, j = 0, k = 0; i < old_size && k < del_size; ++i) {
00111 if (del_pos[k] == i) {
00112 ++k;
00113 continue;
00114 }
00115 if (CoinAbs(ov[i] - nv[j]) > etol) {
00116 _change_pos.push_back(j);
00117 }
00118 ++j;
00119 }
00120 if (old_size - i > new_size - j)
00121 throw BCP_fatal_error("BCP_vec_change::BCP_vec_change() : \n \
00122 old_vec has entries not in new_vec but not listed in del_pos.\n");
00123 for ( ; i < old_size; ++i, ++j) {
00124 if (CoinAbs(ov[i] - nv[j]) > etol) {
00125 _change_pos.push_back(j);
00126 }
00127 }
00128 const int change_size = _change_pos.size();
00129 _values.reserve(change_size + new_size - j);
00130 for (i = 0; i < change_size; ++i) {
00131 _values.unchecked_push_back(nv[_change_pos[i]]);
00132 }
00133 _values.append(nv.entry(j), nv.end());
00134 }
00135
00137 BCP_vec_change(BCP_buffer& buf) {
00138 unpack(buf);
00139 }
00140
00142 ~BCP_vec_change() {}
00148 BCP_storage_t storage() const { return _storage; }
00149
00152 const BCP_vec<T>& explicit_vector() const {
00153 if (_storage != BCP_Storage_Explicit)
00154 throw BCP_fatal_error("\
00155 BCP_vec_change::explicit_vector() : non-explicit storage!\n");
00156 return _values;
00157 }
00158
00161 int storage_size() const {
00162 return (_del_pos.size() + _change_pos.size()) * sizeof(int) +
00163 _values.size() * sizeof(T);
00164 }
00165
00175 void update(const BCP_vec_change<T>& change) {
00176 switch (change.storage()) {
00177 case BCP_Storage_Explicit:
00178 _storage = BCP_Storage_Explicit;
00179 _del_pos.clear();
00180 _change_pos.clear();
00181 _values = change._values;
00182 return;
00183
00184 case BCP_Storage_NoData:
00185 _storage = BCP_Storage_NoData;
00186 _del_pos.clear();
00187 _change_pos.clear();
00188 _values.clear();
00189 return;
00190
00191 default:
00192 if (_storage != BCP_Storage_Explicit)
00193 throw BCP_fatal_error("\
00194 trying to update a non-explicit storage with another non-explicit!\n");
00195 _values.erase_by_index(change._del_pos);
00196 const int ch_size = change._change_pos.size();
00197 for (int i = 0; i < ch_size; ++i) {
00198 _values[change._change_pos[i]] = change._values[i];
00199 }
00200 _values.append(change._values.entry(ch_size), change._values.end());
00201 }
00202 }
00208 void pack(BCP_buffer& buf) const {
00209 const int st = _storage;
00210 buf.pack(st).pack(_del_pos).pack(_change_pos).pack(_values);
00211 }
00213 void unpack(BCP_buffer& buf) {
00214 _del_pos.clear();
00215 _change_pos.clear();
00216 _values.clear();
00217 int st;
00218 buf.unpack(st).unpack(_del_pos).unpack(_change_pos).unpack(_values);
00219 _storage = static_cast<BCP_storage_t>(st);
00220 }
00222 };
00223
00224 #endif