stlab.adobe.com Adobe Systems Incorporated

sequence_model.hpp

Go to the documentation of this file.
00001 /*
00002     Copyright 2005-2007 Adobe Systems Incorporated
00003     Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
00004     or a copy at http://stlab.adobe.com/licenses.html)
00005 */
00006 
00007 /******************************************************************************/
00008 
00009 #ifndef ADOBE_SEQUENCE_MODEL_HPP
00010 #define ADOBE_SEQUENCE_MODEL_HPP
00011 
00012 /******************************************************************************/
00013 
00014 #include <list>
00015 #ifdef ADOBE_STD_SERIALIZATION
00016     #include <iostream>
00017 #endif
00018 
00019 #include <boost/bind.hpp>
00020 #include <boost/next_prior.hpp>
00021 #include <boost/operators.hpp>
00022 #include <boost/static_assert.hpp>
00023 
00024 #include <adobe/algorithm/copy.hpp>
00025 #include <adobe/algorithm/find.hpp>
00026 #include <adobe/algorithm/for_each.hpp>
00027 #include <adobe/copy_on_write.hpp>
00028 #include <adobe/poly_sequence_controller.hpp>
00029 #include <adobe/poly_sequence_view.hpp>
00030 #include <adobe/poly_sequence_model.hpp>
00031 #include <adobe/sequence_model_fwd.hpp>
00032 #include <adobe/typeinfo.hpp>
00033 #include <adobe/vector.hpp>
00034 
00035 /******************************************************************************/
00036 
00037 namespace adobe {
00038 
00039 /******************************************************************************/
00040 
00041 template <typename T>
00042 class sequence_model
00043 {
00044 public:
00046     typedef T                                          value_type;
00048     typedef std::size_t                                size_type;
00050     typedef copy_on_write<value_type>                  cow_value_type;
00052     typedef sequence_key<T>                            key_type;
00054     typedef typename poly_sequence_view<T>::type       poly_sequence_view_type;
00056     typedef typename poly_sequence_controller<T>::type poly_sequence_controller_type;
00057 
00058     BOOST_STATIC_ASSERT((sizeof(key_type) == sizeof(void*)));
00059 
00060     static bool interface_requires_std_rtti()
00061     { return adobe::type_info<T>().requires_std_rtti(); }
00062 
00063     static cow_value_type at(key_type key)
00064     { return *key.value_m; }
00065 
00066     void push_back(const value_type& value)
00067     {
00068         storage_m.push_back(cow_value_type(value));
00069 
00070         for_each(view_set_m, boost::bind(&poly_sequence_view_type::extend,
00071                                          _1,
00072                                          key_type::nkey,
00073                                          key_type(*--storage_m.end()),
00074                                          boost::cref(storage_m.back())));
00075     }
00076 
00077     void set(key_type key, const value_type& value)
00078     {
00079         if (!is_valid(key))
00080             return;
00081 
00082         storage_iterator iter(iterator_for(key));
00083 
00084         *iter = cow_value_type(value);
00085 
00086         for_each(view_set_m, boost::bind(&poly_sequence_view_type::refresh,
00087                                          _1,
00088                                          key,
00089                                          boost::cref(*iter)));
00090     }
00091 
00092     void insert_set(key_type before, const vector<value_type>& value_set)
00093     {
00094         storage_iterator before_iterator(iterator_for(before));
00095         vector<key_type> extend_key_set;
00096 
00097         for (typename vector<value_type>::const_iterator iter(value_set.begin()),
00098              last(value_set.end()); iter != last; ++iter)
00099         {
00100             storage_iterator result(storage_m.insert(before_iterator, cow_value_type(*iter)));
00101 
00102             extend_key_set.push_back(key_type(*result));
00103         }
00104 
00105         for_each(view_set_m, boost::bind(&poly_sequence_view_type::extend_set,
00106                                          _1,
00107                                          before,
00108                                          extend_key_set));
00109     }
00110 
00111     void insert(key_type before, const value_type& value)
00112     {
00113         storage_iterator result(storage_m.insert(iterator_for(before),
00114                                                  cow_value_type(value)));
00115 
00116         for_each(view_set_m, boost::bind(&poly_sequence_view_type::extend,
00117                                          _1,
00118                                          before,
00119                                          key_type(*result),
00120                                          boost::cref(*result)));
00121     }
00122 
00123     void erase(const vector<key_type>& key_set)
00124     {
00125         typedef typename vector<key_type>::const_iterator const_iterator;
00126 
00127         for (const_iterator iter(key_set.begin()), last(key_set.end());
00128              iter != last; ++iter)
00129             storage_m.erase(iterator_for(*iter));
00130 
00131         for_each(view_set_m, boost::bind(&poly_sequence_view_type::erase,
00132                                          _1,
00133                                          boost::cref(key_set)));
00134     }
00135 
00136     void clear()
00137     {
00138         storage_m.clear();
00139 
00140         for_each(view_set_m, boost::bind(&poly_sequence_view_type::clear,
00141                                          _1));
00142     }
00143 
00149     void attach_view(poly_sequence_view_type& view);
00153     void detach_view(poly_sequence_view_type& view);
00154 
00161     void attach_controller(poly_sequence_controller_type& controller);
00165     void detach_controller(poly_sequence_controller_type& controller);
00166 
00167 private:
00168     #ifndef ADOBE_NO_DOCUMENTATION
00169 
00170     typedef std::list<cow_value_type>       storage_type;
00171     typedef typename storage_type::iterator storage_iterator;
00172 
00173     static bool is_valid(key_type k)
00174     { return k != key_type::nkey; }
00175 
00176     size_type size() const { return storage_m.size(); }
00177     bool      empty() const { return storage_m.empty(); }
00178 
00179     storage_iterator iterator_for(key_type key) const
00180     {
00181         storage_type& storage(const_cast<storage_type&>(storage_m));
00182 
00183         if (!is_valid(key))
00184             return storage.end();
00185 
00186         // Ugh -- linear search through the list to find the key.
00187         //
00188         // REVISIT (fbrereto) : Is there any way to make this faster? Perhaps a
00189         //                      cache of some kind to binary-search the key set,
00190         //                      retrieving an iterator? Using table_index?
00191 
00192         for (storage_iterator iter(storage.begin()), last(storage.end());
00193              iter != last; ++iter)
00194             if (key_type(*iter) == key)
00195                 return iter;
00196 
00197         return storage.end();
00198     }
00199 
00200     typedef vector<poly_sequence_view_type*>       view_set_t;
00201     typedef vector<poly_sequence_controller_type*> controller_set_t;
00202 
00203     storage_type                           storage_m;
00204     view_set_t                             view_set_m;
00205     controller_set_t                       controller_set_m;
00206     auto_ptr<typename poly_sequence_model<T>::type> poly_m;
00207 
00208     // ADOBE_NO_DOCUMENTATION
00209     #endif
00210 };
00211 
00212 /******************************************************************************/
00213 
00214 template <typename T>
00215 void sequence_model<T>::attach_view(poly_sequence_view_type& view)
00216 {
00217     typename view_set_t::iterator found(adobe::find(view_set_m, &view));
00218 
00219     if (found != view_set_m.end())
00220         return;
00221 
00222     view_set_m.push_back(&view);
00223 
00224     view.clear();
00225 
00226     if (empty())
00227         return;
00228 
00229     // tell the view everything possible about the current state of the model
00230 
00231     vector<key_type> extend_key_set;
00232 
00233     for (storage_iterator iter(storage_m.begin()), last(storage_m.end());
00234          iter != last; ++iter)
00235         extend_key_set.push_back(key_type(*iter));
00236 
00237     view.extend_set(key_type::nkey, extend_key_set);
00238 }
00239 
00240 /******************************************************************************/
00241 
00242 template <typename T>
00243 void sequence_model<T>::detach_view(poly_sequence_view_type& view)
00244 {
00245     typename view_set_t::iterator found(adobe::find(view_set_m, &view));
00246 
00247     if (found == view_set_m.end())
00248         return;
00249 
00250     view_set_m.erase(found);
00251 }
00252 
00253 /******************************************************************************/
00254 
00255 template <typename T>
00256 void sequence_model<T>::attach_controller(poly_sequence_controller_type& controller)
00257 {
00258     typename controller_set_t::iterator found(adobe::find(controller_set_m, &controller));
00259 
00260     if (found != controller_set_m.end())
00261         return;
00262 
00263     controller_set_m.push_back(&controller);
00264 
00265     if (poly_m.get() == 0)
00266         poly_m.reset(new typename poly_sequence_model<T>::type(boost::ref(*this)));
00267 
00268     controller.monitor_sequence(*poly_m);
00269 }
00270 
00271 /******************************************************************************/
00272 
00273 template <typename T>
00274 void sequence_model<T>::detach_controller(poly_sequence_controller_type& controller)
00275 {
00276     typename controller_set_t::iterator found(adobe::find(controller_set_m, &controller));
00277 
00278     if (found == controller_set_m.end())
00279         return;
00280 
00281     controller_set_m.erase(found);
00282 }
00283 
00284 /******************************************************************************/
00285 
00286 } // namespace adobe
00287 
00288 /******************************************************************************/
00289 // ADOBE_SEQUENCE_MODEL_HPP
00290 #endif
00291 
00292 /******************************************************************************/

Copyright © 2006-2007 Adobe Systems Incorporated.

Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy.

Search powered by Google