From: Sean P. <sp...@ad...> - 2007-05-09 21:06:24
|
If you saw the release notes for 1.0.27 then you saw mention of the version_0 library - The point of version_0 is to lock down a small number of types, fully specify their binary format, and have interfaces that we'd be willing to maintain support for going forward. This is worked was prompted by an Adobe project that is wrapping sections of ASL into a DLL - but learning how to deal with versioning has been on my to-do list for some time. I plan to have things fully documented for 1.0.28 but I just finished stabilizing some code in //submission (with Mat's help) and wanted to give developers a heads up. If you are developing on ASL - read this! Two of the version_0 libraries are vector and closed hash. ---- adobe::vector<> is very similar to std::vector<> - without getting into the specifics - one major change is that array_t is being replaced with vector<any_regular_t>. The impact here on code using array_t is the following: array_t is no longer a copy-on-write type. Copying of an array_t was never that cheap (kicking a refcount protected by a mutex) - but the widget library currently seriously abuses copying arrays. I'll be working to clean some of this out. The array_t is movable - this means that you can return it from a function for assignment or copy construction without penalty: array_t x; x = f(); // the function result is moved. I'm using Dave Abrahams move library (with some fixes) - this has some implications which I'm still working through and move doesn't seem to be helping much so don't consider movability a given - you can however, always know that swap() is cheap. copy-ctor is no long non-throwing. This impacts any composite types that have an array_t as a member. For the composite type to be regular, you must provide your own swap() (that does member wise swap) and should provide a transactional assignment (using adobe/ algorithm/assign.hpp which is written in terms of swap). Because of move, the compiler generated assignment operator for composite types will have a non-const rvalue. Depending on the way the wind is blowing, this will generate a compile time error - consider that an opportunity to write a proper assignment. Indexing is no longer bounds checked - the final release will include a conditional to disable the index operator so you can review your usage. The old array_t::push_back() took any type, there are a couple of helper functions in array.hpp to help with converting code that relies on this. I haven't yet decided if I'll keep these helper functions, perhaps in a more generic form, or just go fix the code using them... so for now consider them already deprecated but feel free to use them to help you get over the hump of converting (hey - I did the work of updating all of ASL!) ---- The larger impact is replacing dictionary_t with a closed_hash_map<name_t, any_regular_t> Here again we are replacing a COW type with a movable type - dictionaries seem to get flung around a lot more often then arrays were also - First thing to be aware of - a dictionary_t is no longer an ordered type, so if you were relying on ordering (such as for set_union operations) then you'll need to create an index using table_index, sort the index, and work through it. I'll be updating the serialization code to do this so that serialization is stable. Indexing into a dictionary_t with operator[] now has _very_ different semantics - The old form would throw if the key wasn't available and worked on const objects. The new version is like std::map or tr1::unordered_map and only works on non const containers and adds the element if it isn't present. There are some helper functions (get_value()) in dictionary.hpp to help with the transition and a conditional to disable indexing while you are converting... Here is a table of the common patterns I've found: old --> new ------------------------------------------------- d[k] get_value(d, k) d.get<T>(k) get_value(d, k).cast<T>() d.get(k, x) get_value(d, k, x); d.set(k, x) d.insert(std::make_pair(k, x)) d.write()[k] d[k] d.inserter() std::inserter(d, d.end()) One current difference between a closed_hash_map<> and a map<> is that the key_type is not constant - you must be a little careful to to write a key value into an item in the container (or it will likely be lost). The reason is that the implementation need to be able to swap elements - I've tried a couple of hacked ways to allow for that but everything I've tried is more grotesque then living with this limitation. Ideally I could simply require that the pair has a copy- ctor taking rvalues and does a non-throwing move... unfortunately std::pair certainly doesn't satisfy this, and adding an adobe::pair (I tried it) breaks so much code that is specialized for std::pair that it doesn't seem worth it. ----- Yes, I've been fixing up a lot of code... In the final 1.0.28 release I'll include more complete notes on updating but I wanted to give folks a heads up on where things are going. Sean |