Boost logo

Boost :

From: Pavel Vozenilek (pavel_vozenilek_at_[hidden])
Date: 2004-09-26 10:43:44


"Pavol Droba" wrote:

> The review of the Smart Container library, written by Thorsten Ottosen
> starts today
>
>
I vote weak YES to accept smart containers into Boost.

In current state the library is missing:
 - small readable code examples
 - support for object factories
 - and other points bellow.

I'd collected quite a few comments on the library.
I didn't yet look into move_ptr and didn't dig
deep in the code.

/Pavel

_____________________________________________________
0. Name of the library should be "Smart Containers"
   (note the plural).

_____________________________________________________
1. It would be nice the very first sentence of docs
   being something as:

"Smart Containers are STL compatible containers
  holding and owning object pointers."

  This would give casual reader quick overview
  whether or not to look deeper.

  The rest like author info etc may follow.

_____________________________________________________
2. docs: the link to license file may be better local.

_____________________________________________________
3. docs, Introduction: the reference to shared_ptr
   may be hyperlinked.

_____________________________________________________
4. docs, Introduction:

" in case of a map"

==>>

" in case of a associative containers like map"

_____________________________________________________
5. docs, Introduction: sentence

   "the objects in an exception safe manner."

   may mention what type of exception safety smart
   containers have or take from.

_____________________________________________________
6. docs, Introduction:

"fool proof pointer storage"

==>>

"pointer storage safer to use mistakes"

"Foool proof" suggests _absolute_ ideal.

_____________________________________________________
7. docs, Introduction: Assignable and
   Copy Constructible could be hyperlinked.

_____________________________________________________
8. docs, Introduction:

"Usually faster than using containers of smart pointers"

This suggests smart pointers in the same design
could happen be faster. I would be really interested
when and how.

_____________________________________________________
9. docs, Introduction:

"Less flexible than containers of smart pointers"

should have example(s) when.

_____________________________________________________
10. docs, Tutorial:

the first example is extremely long.

There should something primitive and up
to 1/2 page first. E.g. farm iterators could
be omitted to keep it small.

It would be better to have few small examples
for each feature than one monster.

There should be <ul> list of features
available in this library and link
to related example.

White space should be minimized in examples.

_____________________________________________________
11. It should be reconsidered whether to name
    files as "ptr_deque.hpp" or "smart_deque.hpp"
    to reduce number of names user needs to keep
    in head while typing code.

    Dtto class names.

_____________________________________________________
12. docs, example in section "Extending a Sequence":

template< class T >
struct my_ptr_vector :
    public boost::ptr_sequence_adapter< std::vector<T*> >

is the class safe against downcast and then delete?
Is it safe to overwrite public functions of parent?
Should be noted just here before one does cut+paste.

_____________________________________________________
13. Clonable concept: it is question whether the function
    allocate_clone() shouldn't be named new_clone(),
    being in sync with delete_clone().

    Other possibility could be allocate_clone/dellocate_clone.

_____________________________________________________
14 Clonable concept: would it make any sense to provide
   support for placement new/delete also?

_____________________________________________________
15. Clonable concept implementation:
    shouldn't there be try/catch in:

    template< class T >
    void delete_clone( const T* t )
    {
        checked_delete( r );
    }

   to enforce the constraints?
   At least it would be useful to have it
   in debug mode to report violation.

_____________________________________________________
16. Clonable conceptL could there be type traits
    is_clonable() for metaprogramming?

_____________________________________________________
17. Clonable concept docs: there's link named
    "(see the beginning of <a>Example 9</a>)
    which is unclear. It should point to code.

_____________________________________________________
18. Clonable concept docs: example how to employ ADL
    and what to do it not present should be added.
    Not every user may be well familiar with the
    technique.

_____________________________________________________
19. docs aestetics: maybe major sections could
    be separated by <br>.

_____________________________________________________
20. Clonable concept: is there any requirement on
    *a_object == *a_cloned_object?

_____________________________________________________
21. Clonable concept: is there anything similar to
     std::nothrow?

    Something as allocate_clone<std::nothrow>(p);

_____________________________________________________
22. Clonable concept: would it be possible to add
    support for object factories? Such thing may
    be useful e.g. for COM or CORBA objects.

_____________________________________________________
23. Clone Manager Concept docs: sentence

"second property allows users to apply custom
 allocators/deallocators for the cloned objects"

It should be made clear whether there could be
one or more custom allocators for cloned objects
involved in single container instance.

_____________________________________________________
24. Clone Manager Concept: there are quite a few
    requirements "must not throw".

    Shouldn't ther be expressed in terms of T?
    E.g. Throws only if T constructor throw.

_____________________________________________________
25. Clone Manager Concept docs: there should be short
    code snippet showing what Clone Manager could
    be used for.

_____________________________________________________
26. Clone Manager Concept docs: it should be explained
    what is 'view_clone_manager' good for, with
    example, and how it affects pointer ownership.

    Maybe it should be reconsidered whether it fits
    well within smart container concept.

_____________________________________________________
27. "The containers are not Assignable"

    - Why not? Why not to call clone on asignee pointers
      and delete_clone on the overwritten pointers?

_____________________________________________________
28. "Ownership can be transferred from a container
     on a per pointer basis".

    This should be better explained, with example.

_____________________________________________________
29. docs, Extending Map example:

       m1.insert( s, new Foo );

    is this exception safe? What if string's
    copy constructor throws?

_____________________________________________________
30. docs, Terminology section, paragraph Ownership:

" smart container or a smart pointer may take
  ownership of an heap-allocated object"

"May take" ???

".. job to delete that object ..."

==>

"... responsibility to destroy that object ..."

_____________________________________________________
31. review question: "Should we remove rbegin()/rend()?
    Boost.Range makes these unnecessary."

    No. One may want to use:

#ifdef XYZ
    typedef ptr_vector<AClass> my_vector_t;
#else
    typedef vector<shared_ptr<AClass> > my_vector_t;
#endif

   and this requires exactly the same interface.

_____________________________________________________
32. docs, References section: Herb Sutter's site can
    be linked here.

_____________________________________________________
33. The mentined "move_ptr" framweorks sounds as
    something what could be standalone Boost library.

_____________________________________________________
34. docs, Future directions section:
    it is not clear (to me) what role the
    'observe()' function has. What idiaom does it support?

_____________________________________________________
35. docs, section "When the stored pointer cannot
    be 0, how do I ...":

    - there may be code snippet example.

_____________________________________________________
36. docs, section "Are the pointer containers faster
    and do they have better memory...":

"The short answer is yes: ..."
==>
"Yes: ..."

_____________________________________________________
37. docs, section "What is polymorphic class problem":

    - an illustrating example could be here.

_____________________________________________________
38. docs, section "Why are inserting member function
    overloaded for both pointers and references?
    REVIEW QUESTION: do we want this behavior?"

   - IMO no. Very confusing.

_____________________________________________________
39. docs question: "Which mutating algorithms are safe
    to use with pointers?"

    Maybe overloads of std::unique etc could be added
    to avoid accidental misuse. Something like:

   namespace std {

      template<...>
      xyz unique(boost::ptr_vector<T>::iterator, ...);

   }

   At least there should be exhaustive list of
   nnt-supported std and Boost algorithms.

_____________________________________________________
40. review question 2: (about ptr_array): yes, should exist.

_____________________________________________________
41. review question 6: (about using Range): why not both?

_____________________________________________________
42. review question 8: (const_begin/const_end): no.
    Have an example with Range for what is useful.

_____________________________________________________
43. review question 9: (key iterator): why is such
    thing needed for? map::iterator->first isn't enough?

_____________________________________________________
44. review question 11: rather no, feels as
    hole into type system.

_____________________________________________________
45. Will there be support for circular_buffer library
    at some time?

    I would ask for Multi Index but don't know enough
    to judge its feasibility.

_____________________________________________________
46. docs, "Library headers" section: the heareds should
    be hyperlinked for convenience.

_____________________________________________________
47. There should be <boost/smart_containers.hpp>
    (note its location and plural at the end).

    Also <boost/smart_containers_fwd.hpp> should exist.

_____________________________________________________
48. What is boost/smart_container/template.hpp for?

And boost/smart_container/detail/undef.hpp?

_____________________________________________________
49. clone_manager.hpp should have

#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif

Similarly move_ptr headers and maybe others.

_____________________________________________________
50. The directory with headers should use plural:
    boost/smart_containers. It is in sync with library name.

_____________________________________________________
51. boost/smart_container/detail/size_undoer.hpp:
    shouldn't ScopeGuard be used instead of this?

    There's copy of Alexandrescu's implementation
    within MultiIndex library.

_____________________________________________________
52. The library should not use sub-namespace detail
    but smart_pointers_detail or so to avoid
    possible clashes.

_____________________________________________________
53. exception.hpp: the function argument should
    not be named 'what' as it is confusing with what()
    function.

_____________________________________________________
54. ptr_array.hpp: typo in:

       throw bad_index( "'replace()' aout of bounds" );

_____________________________________________________
55. exception.hpp: the names bad_smart_container_operation,
    bad_index and bad_pointer are too generic,
    polluting namespace and and non-descriptive.

    They should be changed to:
     - smart_containers_exception_base
     - smart_containers_invalid_index_value
     - smart_containers_null_pointer_inserted

   These exceptions should be declared in
   <boost/smart_containers_fwd.hpp>.

_____________________________________________________
56. There should be ptr_slist.hpp and
    maybe ptr_hash_XYZ variant.

    Support for future boost::unordered_map/set
    could be added too.

_____________________________________________________
57. Maybe boost::tuple could be supported as well.

_____________________________________________________
58. The documentation could contain result of
    a bechmark, how faster is access via ptr_vector
    copmpared to vector<shared_ptr> for example.

_____________________________________________________
59. clone_manager.hpp: in delete clone BOOST_ASSERT
    could be added:

    template< class T >
    void delete_clone( const T* r )
    {
        BOOST_ASSERT(r);
        checked_delete( r );
    }

    There are for sure many other places.

_____________________________________________________
60. source code refers to old name of the library
    in comments:

/**
 * Pointer-Container Library

_____________________________________________________
61. Source should be cleaned up from remnants like:

//#undef BOOST_FORWARD_TYPEDEF
//#undef BOOST_SMART_CONTAINER_RELEASE_AND_CLONE

in ptr_list.hpp.

_____________________________________________________
62.ptr_list.hpp:

    template< typename T, typename A >
    inline ptr_list<T,A>* allocate_clone( const ptr_list<T,A>& r )
    {
        return r.clone().release();
    }

could clone() fail and return 0? What if there's
special allocator returning 0 instead of throwing?

_____________________________________________________
63. The source code surely won't suffer from having
    some overview sections. Like what is this file
    for, what are related files to look on etc.

_____________________________________________________
64. documentation should have section how to
    'smartify' an user container, preferably with step
     by step example.

_____________________________________________________
65. details/scoped_deleter.hpp: there seems no need
    for scoped_array here (only to bloat executable
    and slower compilation).

_____________________________________________________
66. detail/reversible_smart_container.hpp, line 373:

            else
                ;
        }

????

_____________________________________________________
67. It would be nice to support systems without
    enabled exceptions (BOOST_NO_EXCEPTIONS).

_____________________________________________________
65. details/scoped_deleter.hpp: member released_
    can be eliminated, Negative value of stored_ could
    have its function.

    IMHO more attention could be taken on
    possible optimoizations here as this class
    feels to be on performance critical path.

    Maybe the dynamically allocated array could
    be optimized away when size == 1.

    Also to avoid code bloat the generic void*
    implementation could be used as core.

_____________________________________________________
66. there's file with funny name map_iterator_old.hpp.

_____________________________________________________
67. detail/map_iterators.hpp: the extremely hard to read
    lines like:

 template< typename I, typename K, typename V > // I = original iterator, K
= key type, V = return value type of operator*()
 class map_iterator : bidirectional_iterator_helper< map_iterator<I,K,V>,
std::pair<K,V>, // V*?
                                                     std::ptrdiff_t,
std::pair<K,V>*, // V*?
                                                     V& >

  Must be rearranged.

_____________________________________________________
68.

Likewise in ptr_map_adapter.hpp:

        typedef BOOST_DEDUCED_TYPENAME
            smart_container::detail::map_iterator<
                       BOOST_DEDUCED_TYPENAME Map::const_reverse_iterator,
                       BOOST_DEDUCED_TYPENAME Map::key_type,
                       const value_type>
                     const_reverse_iterator;

    I have problem
to find what
    is end and what
        is beginning here

_____________________________________________________
69. ptr_map_adapter.hpp:
    shouldn't operator[] be unsafe, check nothing
    fast operation and at() the safe one?

    Right now they both default to the same call
    lookup(). This is againts STL habits.

    IMHO BOOST_ASSERT + potetially unsafe operator[]
    should be used.

_____________________________________________________
69. ptr_map_adapter.hpp: should have
      #include <memory>

    because of using std::auto_ptr.

_____________________________________________________
70. ptr_map_adapter.hpp: file ends with funny

    #endif

_____________________________________________________
72. ptr_predicate.hpp:

#if defined(_MSC_VER) && (_MSC_VER >= 1200)
    #pragma once
#endif

should be realigned for aesthetic reasons.

_____________________________________________________
72. ptr_predicate.hpp: maybe name
    "pointed_equal_to" is better than
    "ptr_equal_to".

_____________________________________________________
73. ptr_predicate.hpp: the functors could have:

struct XYZ {
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
     char dummy_; // BCB would by default use 8 bytes for empty class
#endif
     ....
   };

optimization for BCB. There's no way to
make it smaller with this compiler and no easier.

_____________________________________________________
74. ptr_set.hpp: the code as:

    template< class Key, class Compare = ptr_less<Key>,
              class CloneManager = heap_clone_manager >
    class ptr_set :

could be rearranged into readable form:

    template
    <
       class Key,
       class Compare = ptr_less<Key>,
       class CloneManager = heap_clone_manager
>
    class ptr_set :

_____________________________________________________
75. There could be some static asserts to avoid one
    trying ptr_vector<int>.

_____________________________________________________
76. Why there is no swap() between smart containers?

    Futhermore one may want operators ==, !=, <, ...

_____________________________________________________
77. detail/associative_smart_container.hpp:
    why is there the "this" in:

       this->remove( i );

    and so like?

_____________________________________________________
78. will ptr_list<...>::sort() work?

_____________________________________________________
79. In debug more there could be check that
    inserted pointer is really unique.

_____________________________________________________
80. Function

    template<class Container, class T, class SmartContainer>
    Container<shared_ptr<T> >
      boost::convert(SmartContainer<T>& cont);

   may come useful sometimes.

   ptr_list<X> cont1;

   vector<shared_ptr<X> > cont2 =
      convert<vector>(cont1);

  E.g. for "legacy" (= pre-smart container) libraries.

_____________________________________________________
EOF


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk