/home/coin/SVN-release/CoinAll-1.1.0/Bcp/src/include/BCP_vector_change.hpp

Go to the documentation of this file.
00001 // Copyright (C) 2000, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
00003 #ifndef _BCP_VECTOR_CHANGE_H
00004 #define _BCP_VECTOR_CHANGE_H
00005 
00006 // This file is fully docified.
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; // runs on old_vec/new_vec/del_pos
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; // runs on old_vec/new_vec/del_pos
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: // must be BCP_Storage_WrtParent:
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

Generated on Sun Nov 14 14:06:29 2010 for Coin-All by  doxygen 1.4.7