Commit MetaInfo

Revision37d9e2b88f6c7049cd2f4358348f392588b26f16 (tree)
Time2013-05-11 12:01:53
Author <exeal@user...>

Log Message

detail.GapVector.insert family now returns an iterator which addresses the inserted element.

Change Summary

Incremental Difference

diff -r d5ce43c2c0d9 -r 37d9e2b88f6c ascension/ascension/corelib/gap-vector.hpp
--- a/ascension/ascension/corelib/gap-vector.hpp Thu May 09 22:14:13 2013 +0900
+++ b/ascension/ascension/corelib/gap-vector.hpp Sat May 11 12:01:53 2013 +0900
@@ -3,7 +3,7 @@
33 * @author exeal
44 * @date 2005-2009 (was gap-buffer.hpp)
55 * @date 2010-10-20 Renamed GapBuffer to GapVector.
6- * @date 2011-2012
6+ * @date 2011-2013
77 */
88
99 #ifndef ASCENSION_GAP_VECTOR_HPP
@@ -52,8 +52,8 @@
5252 std::random_access_iterator_tag, Reference, typename Target::difference_type> {
5353 public:
5454 typedef GapVectorIterator<Target, Pointer, Reference> Self;
55- GapVectorIterator() /*noexcept*/ : target_(nullptr) {}
56- GapVectorIterator(const Target& target, Pointer position) /*noexcept*/
55+ GapVectorIterator() BOOST_NOEXCEPT : target_(nullptr) {}
56+ GapVectorIterator(const Target& target, Pointer position) BOOST_NOEXCEPT
5757 : target_(&target), current_(position - target.first_) {}
5858 template<typename Pointer2, typename Reference2>
5959 GapVectorIterator(const GapVectorIterator<Target, Pointer2, Reference2>& other)
@@ -63,36 +63,36 @@
6363 current_ = other.current_;
6464 return *this;
6565 }
66- const Pointer get() const /*noexcept*/ {return target()->first_ + current_;}
67- const Target* target() const /*noexcept*/ {return target_;}
68- private:
69- difference_type offset() const /*noexcept*/ {
66+ const Pointer get() const BOOST_NOEXCEPT {return target()->first_ + current_;}
67+ difference_type offset() const BOOST_NOEXCEPT {
7068 return (get() <= target_->gapFirst_) ?
7169 get() - target_->first_ :
7270 get() - target_->gapLast_ + target_->gapFirst_ - target_->first_;
7371 }
72+ const Target* target() const BOOST_NOEXCEPT {return target_;}
73+ private:
7474 friend class boost::iterator_core_access;
7575 void advance(difference_type n) {
7676 if(get() + n >= target_->gapFirst_ && get() + n < target_->gapLast_)
7777 n += target_->gap();
7878 current_ += n;
7979 }
80- void decrement() /*noexcept*/ {
80+ void decrement() BOOST_NOEXCEPT {
8181 if(get() != target_->gapLast_)
8282 --current_;
8383 else
8484 current_ = (target()->gapFirst_ - target()->first_) - 1;
8585 }
86- reference dereference() const /*noexcept*/ {
86+ reference dereference() const BOOST_NOEXCEPT {
8787 return target_->first_[current_];
8888 }
89- difference_type distance_to(const GapVectorIterator& other) const /*noexcept*/ {
89+ difference_type distance_to(const GapVectorIterator& other) const BOOST_NOEXCEPT {
9090 return current_ - other.current_;
9191 }
92- bool equal(const GapVectorIterator& other) const /*noexcept*/ {
92+ bool equal(const GapVectorIterator& other) const BOOST_NOEXCEPT {
9393 return current_ == current_;
9494 }
95- void increment() /*noexcept*/ {
95+ void increment() BOOST_NOEXCEPT {
9696 assert(get() != target_->gapFirst_);
9797 ++current_;
9898 if(get() == target_->gapFirst_)
@@ -112,9 +112,6 @@
112112 template<typename T, typename Allocator = std::allocator<T>>
113113 class GapVector : boost::totally_ordered<GapVector<T, Allocator>> {
114114 public:
115-
116- // member types ///////////////////////////////////////////////////////////////////////
117-
118115 /// A type represents the allocator class.
119116 typedef Allocator allocator_type;
120117 /// A type counts the number of elements.
@@ -141,11 +138,10 @@
141138 /// A type provides a random-access iterator can read any element in the content.
142139 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
143140
144-
145- // core member functions //////////////////////////////////////////////////////////////
146-
141+ /// @name Construct/Copy/Destroy
142+ /// @{
147143 /**
148- * Constructor.
144+ * Constructs an empty gap vector, using the specified allocator.
149145 * @param allocator The allocator object
150146 */
151147 explicit GapVector(const allocator_type& allocator = allocator_type()) :
@@ -155,20 +151,21 @@
155151 gapFirst_(first_), gapLast_(last_) {}
156152
157153 /**
158- * Constructor specifies repition of a specified number of elements.
159- * @param count The number of elements in the constructed content
154+ * Constructs a gap vector with @a n copies of value, using the specified allocator.
155+ * @param n The number of elements in the constructed content
160156 * @param value The value of elements in the constructed content
161157 * @param allocator The allocator object
162158 */
163- GapVector(size_type count, const_reference value,
159+ GapVector(size_type n, const_reference value,
164160 const allocator_type& allocator = allocator_type()) : allocator_(allocator),
165- first_(allocator_.allocate(count, 0)), last_(first_ + count),
161+ first_(allocator_.allocate(count, 0)), last_(first_ + n),
166162 gapFirst_(first_), gapLast_(last_) {
167- insert(0, count, value);
163+ insert(0, n, value);
168164 }
169165
170166 /**
171- * Constructor copies a range of a gap vector.
167+ * Constructs a gap vector equal to the range <code>[first,last)</code>, using the
168+ * specified allocator.
172169 * @tparam Inputiterator The input iterator
173170 * @param first The first element in the range of elements to be copied
174171 * @param last The last element in the range of elements to be copied
@@ -247,14 +244,14 @@
247244 *p = std::move(other.first_ + (p - first_));
248245 other.first_ = other.last_ = other.gapFirst_ = other.gapLast_ = nullptr;
249246 }
250-
247+#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
251248 /**
252249 * Constructor with an initializer list.
253250 * @param values The initializer list to initialize the elements of the container with
254251 * @param allocator The allocator object
255252 */
256253 GapVector(std::initializer_list<value_type> values, const allocator_type& allocator);
257-
254+#endif // !BOOST_NO_CXX11_HDR_INITIALIZER_LIST
258255 /// Destructor.
259256 ~GapVector() {release();}
260257
@@ -277,7 +274,9 @@
277274 GapVector<value_type, allocator_type>(std::forward(other)).swap(*this);
278275 return *this;
279276 }
280-
277+#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
278+ GapVector& operator=(std::initializer_list<value_type> values);
279+#endif // !BOOST_NO_CXX11_HDR_INITIALIZER_LIST
281280 /**
282281 * Assigns a range of elements.
283282 * @tparam InputIterator The input iterator type gives the range
@@ -292,20 +291,24 @@
292291
293292 /**
294293 * Assigns a number of elements.
295- * @param count The new size of the container
294+ * @param n The new size of the container
296295 * @param value The value to initialize elements of the container with
297296 */
298- void assign(size_type count, const_reference value) {
299- GapVector<value_type, allocator_type> temp(count, value);
297+ void assign(size_type n, const_reference value) {
298+ GapVector<value_type, allocator_type> temp(n, value);
300299 *this = std::move(temp);
301300 }
301+#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
302+ void assign(std::initializer_list<value_type> values);
303+#endif // !BOOST_NO_CXX11_HDR_INITIALIZER_LIST
302304
303305 /// Returns the allocator associated with the container.
304306 allocator_type allocator() const {return allocator_;}
307+ /// @}
305308
306309
307- // element accesses ///////////////////////////////////////////////////////////////////
308-
310+ /// @name Element Access
311+ /// @{
309312 /**
310313 * Returns a reference to the element at a specified position.
311314 * @param position The position of the element to return
@@ -335,7 +338,7 @@
335338 * @param position The position of the element to return
336339 * @return A reference to the requested element
337340 */
338- reference operator[](size_type position) /*throw()*/ {
341+ reference operator[](size_type position) BOOST_NOEXCEPT {
339342 return first_[(first_ + position < gapFirst_) ? position : position + gap()];
340343 }
341344
@@ -344,75 +347,75 @@
344347 * @param position The position of the element to return
345348 * @return A reference to the requested element
346349 */
347- const_reference operator[](size_type position) const /*throw()*/ {
350+ const_reference operator[](size_type position) const BOOST_NOEXCEPT {
348351 return first_[(first_ + position < gapFirst_) ? position : position + gap()];
349352 }
350353
351354 /// Returns a reference to the first element in the container.
352- reference front() /*throw()*/ {return (*this)[0];}
355+ reference front() BOOST_NOEXCEPT {return (*this)[0];}
353356
354357 /// Returns a reference to the first element in the container.
355- const_reference front() const /*throw()*/ {return (*this)[0];}
358+ const_reference front() const BOOST_NOEXCEPT {return (*this)[0];}
356359
357360 /// Returns a reference to the last element in the container.
358- reference back() /*throw()*/ {return (*this)[size() - 1];}
361+ reference back() BOOST_NOEXCEPT {return (*this)[size() - 1];}
359362
360363 /// Returns a const reference to the last element in the container.
361- const_reference back() const /*throw()*/ {return (*this)[size() - 1];}
362-
364+ const_reference back() const BOOST_NOEXCEPT {return (*this)[size() - 1];}
365+ /// @}
363366
364- // iterators //////////////////////////////////////////////////////////////////////////
365-
366- /// Returns an iterator to the first element of the container.
367- iterator begin() /*noexcept*/ {return iterator(*this, first_);}
367+ /// @name Iterators
368+ /// @{
369+ /** Returns an iterator to the first element of the container. */
370+ iterator begin() BOOST_NOEXCEPT {return iterator(*this, first_);}
368371
369372 /// Returns an iterator to the first element of the container.
370- const_iterator begin() const /*noexcept*/ {return const_iterator(*this, first_);}
373+ const_iterator begin() const BOOST_NOEXCEPT {return const_iterator(*this, first_);}
371374
372375 /// Returns an iterator to the first element of the container.
373- const_iterator cbegin() const /*noexcept*/ {return begin();}
374-
375- /// Returns an iterator to the element following the last element of the container.
376- iterator end() /*noexcept*/ {return iterator(*this, last_);}
376+ const_iterator cbegin() const BOOST_NOEXCEPT {return begin();}
377377
378378 /// Returns an iterator to the element following the last element of the container.
379- const_iterator end() const /*noexcept*/ {return const_iterator(*this, last_);}
379+ iterator end() BOOST_NOEXCEPT {return iterator(*this, last_);}
380380
381381 /// Returns an iterator to the element following the last element of the container.
382- const_iterator cend() const /*noexcept*/ {return end();}
382+ const_iterator end() const BOOST_NOEXCEPT {return const_iterator(*this, last_);}
383+
384+ /// Returns an iterator to the element following the last element of the container.
385+ const_iterator cend() const BOOST_NOEXCEPT {return end();}
383386
384387 /// Returns a reverse iterator to the first element of the reversed container.
385- reverse_iterator rbegin() /*noexcept*/ {return reverse_iterator(end());}
388+ reverse_iterator rbegin() BOOST_NOEXCEPT {return reverse_iterator(end());}
386389
387390 /// Returns a reverse iterator to the first element of the reversed container.
388- const_reverse_iterator rbegin() const /*noexcept*/ {return const_reverse_iterator(end());}
391+ const_reverse_iterator rbegin() const BOOST_NOEXCEPT {return const_reverse_iterator(end());}
389392
390393 /// Returns a reverse iterator to the first element of the reversed container.
391- const_reverse_iterator crbegin() const /*noexcept*/ {return rbegin();}
394+ const_reverse_iterator crbegin() const BOOST_NOEXCEPT {return rbegin();}
392395
393396 /// Returns a reverse iterator to the element following the last element of the
394397 /// reversed container.
395- reverse_iterator rend() /*noexcept*/ {return reverse_iterator(begin());}
396-
397- /// Returns a reverse iterator to the element following the last element of the
398- /// reversed container.
399- const_reverse_iterator rend() const /*noexcept*/ {return const_reverse_iterator(begin());}
398+ reverse_iterator rend() BOOST_NOEXCEPT {return reverse_iterator(begin());}
400399
401400 /// Returns a reverse iterator to the element following the last element of the
402401 /// reversed container.
403- const_reverse_iterator crend() const /*noexcept*/ {return rend();}
404-
402+ const_reverse_iterator rend() const BOOST_NOEXCEPT {return const_reverse_iterator(begin());}
405403
406- // capacities /////////////////////////////////////////////////////////////////////////
404+ /// Returns a reverse iterator to the element following the last element of the
405+ /// reversed container.
406+ const_reverse_iterator crend() const BOOST_NOEXCEPT {return rend();}
407407
408- /// Returns @c true if the container is empty.
409- bool empty() const /*noexcept*/ {return size() == 0;}
408+ /// @name Capacity
409+ /// @note @c GapVector does not provide @c resize methods.
410+ /// @{
411+ /** Returns @c true if the container is empty. */
412+ bool empty() const BOOST_NOEXCEPT {return size() == 0;}
410413
411414 /// Returns the number of elements in the container.
412- size_type size() const /*noexcept*/ {return capacity() - gap();}
415+ size_type size() const BOOST_NOEXCEPT {return capacity() - gap();}
413416
414417 /// Returns the maximum size of the container.
415- size_type maxSize() const /*noexcept*/ {return allocator_.max_size();}
418+ size_type maxSize() const BOOST_NOEXCEPT {return allocator_.max_size();}
416419
417420 /**
418421 * Sets the capacity of the container to at least @a size.
@@ -420,15 +423,28 @@
420423 */
421424 void reserve(size_type newCapacity) {reallocate(newCapacity);}
422425
423- /// Returns the number of elements that the content could contain without allocating
424- /// more storage.
425- size_type capacity() const /*noexcept*/ {return last_ - first_;}
426+ /**
427+ * Resizes the container to contain @a count elements.
428+ * @param count The new size of the container
429+ */
430+ void resize(size_type size);
431+
432+ /**
433+ * Resizes the container to contain @a count elements.
434+ * @param count The new size of the container
435+ * @param value The value to initialize the new elements with
436+ */
437+ void resize(size_type count, const_reference value);
438+
439+ /// Returns the total number of elements that the gap vector can hold without requiring reallocation.
440+ size_type capacity() const BOOST_NOEXCEPT {return last_ - first_;}
426441
427442 /// Requests the removal of unused capacity.
428443 void shrinkToFit() {reallocate(size());}
444+ /// @}
429445
430-
431- // modifiers //////////////////////////////////////////////////////////////////////////
446+ /// @name Modifiers
447+ /// @{
432448
433449 /// Removes all elements from the container.
434450 void clear() {erase(begin(), end());} // TODO: Follow std.vector.clear semantics.
@@ -438,11 +454,12 @@
438454 * @param position The element before which the content will be inserted
439455 * @param value The element value to insert
440456 */
441- void insert(const_iterator position, const_reference value) {
457+ iterator insert(const_iterator position, const_reference value) {
442458 makeGapAt(position.get());
443459 *(gapFirst_++) = value;
444460 if(gapFirst_ == gapLast_)
445461 reallocate(capacity() * 2);
462+ return iterator(*this, gapFirst_);
446463 }
447464
448465 /**
@@ -450,26 +467,28 @@
450467 * @param position The element before which the content will be inserted
451468 * @param value The element value to insert
452469 */
453- void insert(const_iterator position, value_type&& value) {
470+ iterator insert(const_iterator position, value_type&& value) {
454471 makeGapAt(position.get());
455472 *(gapFirst_++) = std::move(value);
456473 if(gapFirst_ == gapLast_)
457474 reallocate(capacity() * 2);
475+ return iterator(*this, gapFirst_);
458476 }
459477
460478 /**
461479 * Inserts elements to the specified position in the container.
462480 * @param position The element before which the content will be inserted
463- * @param count The number of the elements to insert
481+ * @param n The number of the elements to insert
464482 * @param value The element value to insert
465483 */
466- void insert(const_iterator position, size_type count, const_reference value) {
484+ iterator insert(const_iterator position, size_type n, const_reference value) {
467485 makeGapAt(first_ + size());
468486 makeGapAt(position.get());
469487 if(static_cast<size_type>(gap()) <= count)
470- reallocate(std::max(capacity() + count + 1, capacity() * 2));
471- std::fill_n(gapFirst_, count, value);
472- gapFirst_ += count;
488+ reallocate(std::max(capacity() + n + 1, capacity() * 2));
489+ std::fill_n(gapFirst_, n, value);
490+ gapFirst_ += n;
491+ return iterator(*this, gapFirst_ - n);
473492 }
474493
475494 /**
@@ -480,28 +499,29 @@
480499 * @param last The end of the range of elements to insert
481500 */
482501 template<typename InputIterator>
483- void insert(const_iterator position, InputIterator first, InputIterator last) {
484- const difference_type c = std::distance(first, last);
485- if(c != 0) {
486- if(c > gap())
487- reallocate(std::max(c + size(), capacity() * 2));
488-// makeGapAt(first_ + size());
489- makeGapAt(position.get());
490- pointer p = const_cast<pointer>(position.get());
491- gapFirst_ = first_ + (uninitializedCopy(first, last, p, allocator_) - first_);
502+ iterator insert(const_iterator position, InputIterator first, InputIterator last) {
503+ const difference_type n = std::distance(first, last);
504+ if(n == 0)
505+ return position;
506+ if(n > gap()) {
507+ const const_iterator::difference_type index = position.offset();
508+ reallocate(std::max(n + size(), capacity() * 2));
509+ position = cbegin() + index;
492510 }
511+// makeGapAt(first_ + size());
512+ makeGapAt(position.get());
513+ pointer p = const_cast<pointer>(position.get());
514+ gapFirst_ = first_ + (uninitializedCopy(first, last, p, allocator_) - first_);
515+ return iterator(*this, gapFirst_ - n);
493516 }
494-
517+#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
495518 /**
496519 * Inserts elements to the specified position in the container.
497520 * @param position The element before which the content will be inserted
498521 * @param values The initializer list to insert the values from
499522 */
500- void insert(const_iterator position, std::initializer_list<value_type> values);
501-
502-// template<typename... Arguments>
503-// iterator emplace(const_iterator position, Arguments&& ...arguments);
504-
523+ iterator insert(const_iterator position, std::initializer_list<value_type> values);
524+#endif // !BOOST_NO_CXX11_HDR_INITIALIZER_LIST
505525 /**
506526 * Removes an element in this gap vector.
507527 * @param position The position of the element to remove
@@ -539,33 +559,24 @@
539559
540560 void pushBack(const_reference value);
541561 void pushBack(value_type&& value);
542-// template<typename... Arguments> void emplaceBack(Arguments&& ...arguments);
562+#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
563+ template<typename... Arguments> void emplace(const_iterator position, Arguments&& ...arguments);
564+ template<typename... Arguments> void emplaceBack(Arguments&& ...arguments);
565+#endif // !BOOST_NO_CXX11_VARIADIC_TEMPLATES
543566 void popBack();
544567
545568 /**
546- * Resizes the container to contain @a count elements.
547- * @param count The new size of the container
548- */
549- void resize(size_type size);
550-
551- /**
552- * Resizes the container to contain @a count elements.
553- * @param count The new size of the container
554- * @param value The value to initialize the new elements with
555- */
556- void resize(size_type count, const_reference value);
557-
558- /**
559569 * Exchanges the elements of two gap vectors.
560570 * @param other A gap vector whose elements to be exchanged
561571 */
562- void swap(GapVector& other) /*noexcept*/ {
572+ void swap(GapVector& other) BOOST_NOEXCEPT {
563573 std::swap(allocator_, other.allocator);
564574 std::swap(first_, other.first_);
565575 std::swap(last_, other.last_);
566576 std::swap(gapFirst_, other.gapFirst_);
567577 std::swap(gapLast_, other.gapLast_);
568578 }
579+ /// @}
569580
570581 private:
571582 // helpers
@@ -573,7 +584,7 @@
573584 for(; first != last; ++first)
574585 allocator_.destroy(first);
575586 }
576- difference_type gap() const /*throw()*/ {return gapLast_ - gapFirst_;}
587+ difference_type gap() const BOOST_NOEXCEPT {return gapLast_ - gapFirst_;}
577588 void makeGapAt(const_pointer position) {
578589 pointer p = const_cast<pointer>(position);
579590 if(position < gapFirst_) {
@@ -617,6 +628,7 @@
617628 gapFirst_ += n;
618629 gapLast_ += n;
619630 }
631+ assert(gapFirst_ == position);
620632 }
621633 void reallocate(size_type newCapacity) {
622634 if(newCapacity > maxSize())
Show on old repository browser