Pavel Vozenilek wrote:
> Hello Jan, > > Few more comments + answers. > > 1. Documentation: can circular_buffer<> be used as > container for stack/queue/priority_queue? Yes, it can be. But I think, it is not necessary to mention it in the documentation explicitly. Rather it is more important to mention that everyone is encouraged to create an adaptor of this container (whatever he/she likes not only stack or queue). > > > 2. When BOOST_NO_EXCEPTION is defined, library > shouldn't throw but call function > throw_exception() from throw_exception.hpp > (or abort). > OK, I will try to follow it. > > 3. This fragment fails: > > struct Test {} > > circular_buffer<Test> a(2); > a.push_back(Test()); > a.push_back(a[0]); > > Instance of Test is overwritten (by construct()) > and not destroyed in second push_back(). > I don't understand this. IMHO there will be 2 copies of Test(). Nothing should be destroyed in the second push_back(). I think, everything is OK. > > This may be problem for insert()s as well. > > I am not sure whether solving this kind of problems > is worth of the increased complexity. I do not know > what Standard mandates for such a circumstances. > > 4. It may be useful to have circular_buffer<> > constructor taking external buffer (e.g. static > or on stack) and using it internally. > > (Feature has some similarity to std::streambuf.) > > External buffer could lead to lower heap > fragmentation in apps. > Maybe. But it will complicate things, because couldn't delete this buffer and I will have to treat this case specially. So, maybe later. > > 5. Currently functions like insert/erase cannot use > reverse iterators (similarly to standard > containers). > > Some structures like LRU could find use for it. > I don't want to bother with this. > > ---------------------------------------------- > > "Jan Gaspar" <[EMAIL PROTECTED]> wrote ... > > > > 3. cb_iterator: is the m_end value needed? > > > > > > It can be computed using 'm_it == m_buff->m_last' in > > > those few (~2) places it is needed and if eliminated, > > > iterator will get smaller (by 30%) and simpler. > > > > Yes, the m_end member is needed. Suppose the circular_buffer is full. Then > > m_buff->m_first == m_buff->m_last. If there is no m_end variable how would > you > > recognize that the iterator points to the beginning or end? > > > a) on compilers I use sizeof(bool) == 4 so removing it would have impact > > b) what about setting m_it == m_buff every time iterator gets to the end?: > > bool is_end() { > return m_buff == m_it; > } > > Operator ++, --, >, +=, -=, == can do the check and if needed they may > fetch the m_buff->m_last. > > Since m_buff is already in some registry the check should impact > performance too much. Should or shouldn't impact performance? What about setting m_it to 0 ? > > > > > 5. In cb_iterator::operator-(): result of the expression > > > ' it < *this' can be saved and not computed second time. > > > > But it is not used second time. > > > My mistake. > > > > 7. cb_iterator::operator!=(): it may be more efficient to code > > > it as 'm_it != it.m_it ...' instead of !operator==(). > > > I do not know if compilers are allowed to change logical > > > expression and if, how good they are in it. > > > > Maybe. But everyone uses it like this. > > > Everyone uses > for (iter i = buff.begin(); i != buff.end(); ++i) > > While only small help, it may have impact in innermost loops. > OK > > > > 8. cb_iterator::operator<(): the ASSERTS here are useless. > > > Function compare() doesn't return anything else > > > than -1/0/1 - I see it. > > > > Yes, they are useless. But > > 1) omitting them doesn't speed up the execution (in general) > > Well, excerpt from MSVC 7 help: > > void main(int p) > { > switch(p){ > case 1: > func1(1); > break; > case 2: > func1(-1); > break; > default: > __assume(0); > // This tells the optimizer that the default > // cannot be reached. As so it does not have to generate > // the extra code to check that 'p' has a value > // not represented by a case arm. This makes the switch > // run faster. > } > } > > > 2) suppose if someone changes the compare() method implementation ... !!!! > > > Then the check should be within compare() > > > 3) this code is clean, you should always provide the default option > > > IMHO not in this case. I struck my eyes. > > However this is all unimportant detail. > OK > > > > 9. OTOH there are places where ASSERT can be inserted: > > > - ensuring two iterators come from the same buffer > > > - checking iterators are within valid range > > > - checking type of iterators is the same (reverse / normal) > > > > circular_buffer is a STL compliant container - no STL container is doing > this. > > > STLport, newer Dinkumware and maybe even Metrowerks STL provides > DEBUG mode. > > I may help you with this. It is however orthogonal to anything > else with the lib and can be added later into finished code. > I will appreciate this. > > > > 14. circular_buffer<>: set_capacity() is not exception safe: > > > if uninitialized_copy() throws it will leak. > > > This problem happens IMHO in many functions (e.g. > > > in constructors). > > > > > > Scope guard can be used to get basic exception safety. > > > > OK, I will try to fix it. > > > I think basic exception safety can be done without performance hit. > Higher level would require a lot of work, for example to protect > insert_n() interrupted in the middle. > > > > 18. both circular_buffer<>::assign(): > > > > > > m_buff = m_alloc.allocate(capacity(), 0); > > > should be > > > m_buff = allocate(n); > > > > > > > No, it is OK. capacity() will be always at least 1. > > > what about > buff.assign(0, Test()) > or > buff.assign(x.begin(), x.begin()) ? > Look at the code again: if (n > capacity()) { destroy(); m_capacity = n; m_buff = m_alloc.allocate(capacity(), 0); m_end = m_buff + capacity(); ..... The expresion in the condition will be false (even if capacity() == 0). > > > > 23. It may be wortwile to check whether A. Alexandrescu's > > > Mojo technique cannot be used within circular_buffer<>. > > > (I have no idea about concrete applicaility here.) > > > > I have no idea what the Mojo technique is. Try to explore it. > > > Mojo is described in article > http://www.moderncppdesign.com/publications/cuj-02-2003.html. > > Performance effect on STLport containers is described in > http://www.stlport.com/dcforum/DCForumID5/682.html. > I will look at it. > > > > 26. circular_buffer<>:: first insert(): some code from here > > > can be shared throughout the library. > > > > I don't know exactly what you mean. > > > Uhh, nothing to share. > > > > 33. circular_buffer<>::insert(Iter, Iter) may contain > > > STATIC_ASSERT check that Iter iterator value is > > > convertible to buffer main data type. > > > Some other functions as well. > > > > > > Iterator traits may be checked as well. > > > > I think, if the value won't be convertible the compilation fails anyway. > > > My point is that instead of ugly error from guts of STL you get more > readable error. OK, I will try. > > > > > 37. Documentation: it would be nice to have documented > > > precondition, postconditions, exceptions > > > thrown etc. Maybe this info can be embedded into > > > Doxygened text. > > > > What do you mean by precondition and postconditions. Give an example. > > > http://www.boost.org/libs/optional/doc/optional.html > OK > > S pozdravom, > /Pavel > > _______________________________________________ > Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost Jano -- Jan Gaspar | [EMAIL PROTECTED] Whitestein Technologies | www.whitestein.com Panenska 28 | SK-81103 Bratislava | Slovak Republic Tel +421(2)5930-0735 | Fax +421(2)5443-5512 _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost