Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE) 00002 // 00003 // This file is part of Olena. 00004 // 00005 // Olena is free software: you can redistribute it and/or modify it under 00006 // the terms of the GNU General Public License as published by the Free 00007 // Software Foundation, version 2 of the License. 00008 // 00009 // Olena is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00016 // 00017 // As a special exception, you may use this file as part of a free 00018 // software project without restriction. Specifically, if other files 00019 // instantiate templates or use macros or inline functions from this 00020 // file, or you compile this file and link it with other files to produce 00021 // an executable, this file does not by itself cause the resulting 00022 // executable to be covered by the GNU General Public License. This 00023 // exception does not however invalidate any other reasons why the 00024 // executable file might be covered by the GNU General Public License. 00025 00026 #ifndef MLN_CORE_INTERNAL_SET_OF_HH 00027 # define MLN_CORE_INTERNAL_SET_OF_HH 00028 00032 00033 # include <vector> 00034 # include <set> 00035 # include <iterator> 00036 # include <algorithm> 00037 00038 # include <mln/core/contract.hh> 00039 # include <mln/core/internal/force_exact.hh> 00040 00041 00042 namespace mln 00043 { 00044 00045 namespace internal 00046 { 00047 00058 template <typename E> 00059 class set_of_ 00060 { 00061 public: 00062 00063 00072 set_of_<E>& insert(const E& elt); 00073 00074 00083 set_of_<E>& remove(const E& elt); 00084 00085 00094 const E& element(unsigned i) const; 00095 00096 00099 unsigned nelements() const; 00100 00101 00108 bool has(const E& elt) const; 00109 00110 00113 bool is_empty() const; 00114 00115 00123 void clear(); 00124 00125 00132 const std::vector<E>& vect() const; 00133 00134 protected: 00135 00137 set_of_(); 00138 00139 private: 00140 00146 mutable std::vector<E> v_; 00147 00148 protected: 00153 std::set<E> s_; 00154 00155 private: 00160 void update_() const; 00161 00163 mutable bool needs_update_; 00164 }; 00165 00166 00177 // FIXME : ambiguous with site_set operator << 00178 // template <typename E> 00179 // std::ostream& operator<<(std::ostream& ostr, const set_of_<E>& s); 00180 00181 00182 00183 # ifndef MLN_INCLUDE_ONLY 00184 00185 template <typename E> 00186 inline 00187 set_of_<E>::set_of_() 00188 { 00189 needs_update_ = false; 00190 } 00191 00192 template <typename E> 00193 inline 00194 set_of_<E>& 00195 set_of_<E>::insert(const E& elt) 00196 { 00197 s_.insert(elt); 00198 if (needs_update_ == false) 00199 needs_update_ = true; 00200 return internal::force_exact< set_of_<E> >(*this); 00201 } 00202 00203 template <typename E> 00204 inline 00205 set_of_<E>& 00206 set_of_<E>::remove(const E& elt) 00207 { 00208 s_.erase(elt); 00209 if (needs_update_ == false) 00210 needs_update_ = true; 00211 return internal::force_exact< set_of_<E> >(*this); 00212 } 00213 00214 template <typename E> 00215 inline 00216 const E& 00217 set_of_<E>::element(unsigned i) const 00218 { 00219 if (needs_update_) 00220 update_(); 00221 mln_precondition(i < v_.size()); 00222 return v_[i]; 00223 } 00224 00225 template <typename E> 00226 inline 00227 unsigned 00228 set_of_<E>::nelements() const 00229 { 00230 if (needs_update_) 00231 update_(); 00232 return v_.size(); 00233 } 00234 00235 template <typename E> 00236 inline 00237 bool 00238 set_of_<E>::has(const E& elt) const 00239 { 00240 return s_.find(elt) != s_.end(); 00241 } 00242 00243 template <typename E> 00244 inline 00245 bool 00246 set_of_<E>::is_empty() const 00247 { 00248 return nelements() == 0; 00249 } 00250 00251 template <typename E> 00252 inline 00253 void 00254 set_of_<E>::clear() 00255 { 00256 v_.clear(); 00257 s_.clear(); 00258 needs_update_ = false; 00259 mln_postcondition(is_empty()); 00260 } 00261 00262 template <typename E> 00263 inline 00264 const std::vector<E>& 00265 set_of_<E>::vect() const 00266 { 00267 if (needs_update_) 00268 update_(); 00269 return v_; 00270 } 00271 00272 template <typename E> 00273 inline 00274 void 00275 set_of_<E>::update_() const 00276 { 00277 mln_precondition(needs_update_); 00278 v_.clear(); 00279 std::copy(s_.begin(), s_.end(), std::back_inserter(v_)); 00280 // no s_.clear() here: 00281 // - we want to keep information up-to-date in s_ 00282 // - we want to save some execution time 00283 needs_update_ = false; 00284 } 00285 00286 // FIXME : ambiguous with site_set operator << 00287 // template <typename E> 00288 // std::ostream& operator<<(std::ostream& ostr, 00289 // const set_of_<E>& s) 00290 // { 00291 // ostr << '['; 00292 // const unsigned n = s.nelements(); 00293 // for (unsigned i = 0; i < n; ++i) 00294 // ostr << s.element(i) 00295 // << (i == s.nelements() - 1 ? ']' : ','); 00296 // return ostr; 00297 // } 00298 00299 # endif // ! MLN_INCLUDE_ONLY 00300 00301 } // end of namespace mln::internal 00302 00303 } // end of namespace mln 00304 00305 00306 #endif // ! MLN_CORE_INTERNAL_SET_OF_HH