1 #ifndef _GLIBMM_ARRAYHANDLE_H
2 #define _GLIBMM_ARRAYHANDLE_H
3
4 /* Copyright (C) 2002 The gtkmm Development Team
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <glibmmconfig.h>
21 #include <glibmm/containerhandle_shared.h>
22
23 namespace Glib
24 {
25
26 namespace Container_Helpers
27 {
28
29 #ifndef DOXYGEN_SHOULD_SKIP_THIS
30
31 /* Count the number of elements in a 0-terminated sequence.
32 */
33 template <class T>
34 inline std::size_t
compute_array_size(const T * array)35 compute_array_size(const T* array)
36 {
37 const T* pend = array;
38
39 while (*pend)
40 ++pend;
41
42 return (pend - array);
43 }
44
45 /* Allocate and fill a 0-terminated array. The size argument
46 * specifies the number of elements in the input sequence.
47 */
48 template <class For, class Tr>
49 typename Tr::CType*
create_array(For pbegin,std::size_t size,Tr)50 create_array(For pbegin, std::size_t size, Tr)
51 {
52 using CType = typename Tr::CType;
53
54 CType* const array = static_cast<CType*>(g_malloc((size + 1) * sizeof(CType)));
55 CType* const array_end = array + size;
56
57 for (CType* pdest = array; pdest != array_end; ++pdest)
58 {
59 // Use & to force a warning if the iterator returns a temporary object.
60 *pdest = Tr::to_c_type(*&*pbegin);
61 ++pbegin;
62 }
63
64 *array_end = CType();
65 return array;
66 }
67
68 template <class For>
69 gboolean*
create_bool_array(For pbegin,std::size_t size)70 create_bool_array(For pbegin, std::size_t size)
71 {
72 gboolean* const array(static_cast<gboolean*>(g_malloc((size + 1) * sizeof(gboolean))));
73 gboolean* const array_end(array + size);
74
75 for (gboolean* pdest(array); pdest != array_end; ++pdest)
76 {
77 *pdest = *pbegin;
78 ++pbegin;
79 }
80
81 *array_end = false;
82 return array;
83 }
84
85 /* Convert from any container that supports forward
86 * iterators and has a size() method.
87 */
88 template <class Tr, class Cont>
89 struct ArraySourceTraits
90 {
91 using CType = typename Tr::CType;
92
get_sizeArraySourceTraits93 static std::size_t get_size(const Cont& cont) { return cont.size(); }
94
get_dataArraySourceTraits95 static const CType* get_data(const Cont& cont, std::size_t size)
96 {
97 return Glib::Container_Helpers::create_array(cont.begin(), size, Tr());
98 }
99
100 static const Glib::OwnershipType initial_ownership = Glib::OWNERSHIP_SHALLOW;
101 };
102
103 // source traits for bools.
104 template <class Cont>
105 struct BoolArraySourceTraits
106 {
107 using CType = gboolean;
108
get_sizeBoolArraySourceTraits109 static std::size_t get_size(const Cont& cont) { return cont.size(); }
110
get_dataBoolArraySourceTraits111 static const CType* get_data(const Cont& cont, std::size_t size)
112 {
113 return Glib::Container_Helpers::create_bool_array(cont.begin(), size);
114 }
115
116 static const Glib::OwnershipType initial_ownership = Glib::OWNERSHIP_SHALLOW;
117 };
118 /* Convert from a 0-terminated array. The Cont argument must be a pointer
119 * to the first element. Note that only arrays of the C type are supported.
120 */
121 template <class Tr, class Cont>
122 struct ArraySourceTraits<Tr, Cont*>
123 {
124 using CType = typename Tr::CType;
125
126 static std::size_t get_size(const CType* array)
127 {
128 return (array) ? Glib::Container_Helpers::compute_array_size(array) : 0;
129 }
130
131 static const CType* get_data(const CType* array, std::size_t) { return array; }
132
133 static const Glib::OwnershipType initial_ownership = Glib::OWNERSHIP_NONE;
134 };
135
136 template <class Tr, class Cont>
137 struct ArraySourceTraits<Tr, const Cont*> : ArraySourceTraits<Tr, Cont*>
138 {
139 };
140
141 /* Convert from a 0-terminated array. The Cont argument must be a pointer
142 * to the first element. Note that only arrays of the C type are supported.
143 * For consistency, the array must be 0-terminated, even though the array
144 * size is known at compile time.
145 */
146 template <class Tr, class Cont, std::size_t N>
147 struct ArraySourceTraits<Tr, Cont[N]>
148 {
149 using CType = typename Tr::CType;
150
151 static std::size_t get_size(const CType*) { return (N - 1); }
152
153 static const CType* get_data(const CType* array, std::size_t) { return array; }
154
155 static const Glib::OwnershipType initial_ownership = Glib::OWNERSHIP_NONE;
156 };
157
158 template <class Tr, class Cont, std::size_t N>
159 struct ArraySourceTraits<Tr, const Cont[N]> : ArraySourceTraits<Tr, Cont[N]>
160 {
161 };
162
163 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
164
165 /**
166 * @ingroup ContHelpers
167 */
168 template <class Tr>
169 class ArrayHandleIterator
170 {
171 public:
172 using CppType = typename Tr::CppType;
173 using CType = typename Tr::CType;
174
175 using iterator_category = std::random_access_iterator_tag;
176 using value_type = CppType;
177 using difference_type = std::ptrdiff_t;
178 using reference = value_type;
179 using pointer = void;
180
181 explicit inline ArrayHandleIterator(const CType* pos);
182
183 inline value_type operator*() const;
184 inline value_type operator[](difference_type offset) const;
185
186 inline ArrayHandleIterator<Tr>& operator++();
187 inline const ArrayHandleIterator<Tr> operator++(int);
188 // these are needed by msvc 2005 when using deque.
189 inline ArrayHandleIterator<Tr>& operator--();
190 inline const ArrayHandleIterator<Tr> operator--(int);
191
192 // All this random access stuff is only there because STL algorithms
193 // usually have optimized specializations for random access iterators,
194 // and we don't want to give away efficiency for nothing.
195 //
196 inline ArrayHandleIterator<Tr>& operator+=(difference_type rhs);
197 inline ArrayHandleIterator<Tr>& operator-=(difference_type rhs);
198 inline const ArrayHandleIterator<Tr> operator+(difference_type rhs) const;
199 inline const ArrayHandleIterator<Tr> operator-(difference_type rhs) const;
200 inline difference_type operator-(const ArrayHandleIterator<Tr>& rhs) const;
201
202 inline bool operator==(const ArrayHandleIterator<Tr>& rhs) const;
203 inline bool operator!=(const ArrayHandleIterator<Tr>& rhs) const;
204 inline bool operator<(const ArrayHandleIterator<Tr>& rhs) const;
205 inline bool operator>(const ArrayHandleIterator<Tr>& rhs) const;
206 inline bool operator<=(const ArrayHandleIterator<Tr>& rhs) const;
207 inline bool operator>=(const ArrayHandleIterator<Tr>& rhs) const;
208
209 private:
210 const CType* pos_;
211 };
212
213 } // namespace Container_Helpers
214
215 // TODO: When we can break ABI, remove this and replace uses of it with std::vector.
216 // We cannot deprecate it yet, because we cannot easily deprecate methods that use it
217 //- for instance, we cannot just override methods that use it as a return type.
218
219 /** This is an intermediate type. When a method takes this, or returns this, you
220 * should use a standard C++ container of your choice, such as std::list or
221 * std::vector.
222 *
223 * However, this is not used in new API. We now prefer to just use std::vector,
224 * which is less flexibile, but makes the API clearer.
225 *
226 * @ingroup ContHandles
227 */
228 template <class T, class Tr = Glib::Container_Helpers::TypeTraits<T>>
229 class ArrayHandle
230 {
231 public:
232 using CppType = typename Tr::CppType;
233 using CType = typename Tr::CType;
234
235 using value_type = CppType;
236 using size_type = std::size_t;
237 using difference_type = std::ptrdiff_t;
238
239 using const_iterator = Glib::Container_Helpers::ArrayHandleIterator<Tr>;
240 using iterator = Glib::Container_Helpers::ArrayHandleIterator<Tr>;
241
242 template <class Cont>
243 inline ArrayHandle(const Cont& container);
244
245 // Take over ownership of an array created by GTK+ functions.
246 inline ArrayHandle(const CType* array, std::size_t array_size, Glib::OwnershipType ownership);
247 inline ArrayHandle(const CType* array, Glib::OwnershipType ownership);
248
249 // Copying clears the ownership flag of the source handle.
250 inline ArrayHandle(const ArrayHandle<T, Tr>& other);
251
252 ~ArrayHandle() noexcept;
253
254 inline const_iterator begin() const;
255 inline const_iterator end() const;
256
257 template <class U>
258 inline operator std::vector<U>() const;
259 template <class U>
260 inline operator std::deque<U>() const;
261 template <class U>
262 inline operator std::list<U>() const;
263
264 template <class Cont>
265 inline void assign_to(Cont& container) const;
266
267 template <class Out>
268 inline void copy(Out pdest) const;
269
270 inline const CType* data() const;
271 inline std::size_t size() const;
272 inline bool empty() const;
273
274 private:
275 std::size_t size_;
276 const CType* parray_;
277 mutable Glib::OwnershipType ownership_;
278
279 // No copy assignment.
280 ArrayHandle<T, Tr>& operator=(const ArrayHandle<T, Tr>&);
281 };
282
283 template <>
284 class GLIBMM_API ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>
285 {
286 public:
287 using Me = ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>;
288 using Tr = Container_Helpers::TypeTraits<bool>;
289
290 using CppType = Tr::CppType;
291 using CType = Tr::CType;
292
293 using value_type = CppType;
294 using size_type = std::size_t;
295 using difference_type = std::ptrdiff_t;
296
297 using const_iterator = Glib::Container_Helpers::ArrayHandleIterator<Tr>;
298 using iterator = Glib::Container_Helpers::ArrayHandleIterator<Tr>;
299
300 template <class Cont>
301 inline ArrayHandle(const Cont& container);
302
303 // Take over ownership of an array created by GTK+ functions.
304 inline ArrayHandle(const CType* array, std::size_t array_size, Glib::OwnershipType ownership);
305 inline ArrayHandle(const CType* array, Glib::OwnershipType ownership);
306
307 // Copying clears the ownership flag of the source handle.
308 inline ArrayHandle(const Me& other);
309
310 ~ArrayHandle() noexcept;
311
312 inline const_iterator begin() const;
313 inline const_iterator end() const;
314
315 // this is inside class definition, so msvc 2005, 2008 and 2010 can compile this code.
316 template <class U>
317 inline operator std::vector<U>() const
318 {
319 #ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
320 return std::vector<U>(this->begin(), this->end());
321 #else
322 std::vector<U> temp;
323 temp.reserve(this->size());
324 Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
325 return temp;
326 #endif
327 }
328
329 // this is inside class definition, so msvc 2005, 2008 and 2010 can compile this code.
330 template <class U>
331 inline operator std::deque<U>() const
332 {
333 #ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
334 return std::deque<U>(this->begin(), this->end());
335 #else
336 std::deque<U> temp;
337 Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
338 return temp;
339 #endif
340 }
341
342 // this is inside class definition, so msvc 2005, 2008 and 2010 can compile this code.
343 template <class U>
344 inline operator std::list<U>() const
345 {
346 #ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
347 return std::list<U>(this->begin(), this->end());
348 #else
349 std::list<U> temp;
350 Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
351 return temp;
352 #endif
353 }
354
355 template <class Cont>
356 inline void assign_to(Cont& container) const;
357
358 template <class Out>
359 inline void copy(Out pdest) const;
360
361 inline const CType* data() const;
362 inline std::size_t size() const;
363 inline bool empty() const;
364
365 private:
366 std::size_t size_;
367 const CType* parray_;
368 mutable Glib::OwnershipType ownership_;
369
370 // No copy assignment.
371 Me& operator=(const Me&);
372 };
373
374 // TODO: Remove this when we can break glibmm API.
375 /** If a method takes this as an argument, or has this as a return type, then you can use a standard
376 * container such as std::list<Glib::ustring> or std::vector<Glib::ustring>.
377 *
378 *
379 * However, this is not used in new API. We now prefer to just use std::vector,
380 * which is less flexibile, but makes the API clearer.
381 *
382 * @ingroup ContHandles
383 */
384 using StringArrayHandle = ArrayHandle<Glib::ustring>;
385
386 /***************************************************************************/
387 /* Inline implementation */
388 /***************************************************************************/
389
390 #ifndef DOXYGEN_SHOULD_SKIP_THIS
391
392 namespace Container_Helpers
393 {
394
395 /**** Glib::Container_Helpers::ArrayHandleIterator<> ***********************/
396
397 template <class Tr>
398 inline ArrayHandleIterator<Tr>::ArrayHandleIterator(const CType* pos) : pos_(pos)
399 {
400 }
401
402 template <class Tr>
403 inline typename ArrayHandleIterator<Tr>::value_type ArrayHandleIterator<Tr>::operator*() const
404 {
405 return Tr::to_cpp_type(*pos_);
406 }
407
408 template <class Tr>
409 inline typename ArrayHandleIterator<Tr>::value_type ArrayHandleIterator<Tr>::operator[](
410 difference_type offset) const
411 {
412 return Tr::to_cpp_type(pos_[offset]);
413 }
414
415 template <class Tr>
416 inline ArrayHandleIterator<Tr>& ArrayHandleIterator<Tr>::operator++()
417 {
418 ++pos_;
419 return *this;
420 }
421
422 template <class Tr>
423 inline const ArrayHandleIterator<Tr> ArrayHandleIterator<Tr>::operator++(int)
424 {
425 return ArrayHandleIterator<Tr>(pos_++);
426 }
427
428 template <class Tr>
429 inline ArrayHandleIterator<Tr>& ArrayHandleIterator<Tr>::operator--()
430 {
431 --pos_;
432 return *this;
433 }
434
435 template <class Tr>
436 inline const ArrayHandleIterator<Tr> ArrayHandleIterator<Tr>::operator--(int)
437 {
438 return ArrayHandleIterator<Tr>(pos_--);
439 }
440
441 template <class Tr>
442 inline ArrayHandleIterator<Tr>&
443 ArrayHandleIterator<Tr>::operator+=(typename ArrayHandleIterator<Tr>::difference_type rhs)
444 {
445 pos_ += rhs;
446 return *this;
447 }
448
449 template <class Tr>
450 inline ArrayHandleIterator<Tr>&
451 ArrayHandleIterator<Tr>::operator-=(typename ArrayHandleIterator<Tr>::difference_type rhs)
452 {
453 pos_ -= rhs;
454 return *this;
455 }
456
457 template <class Tr>
458 inline const ArrayHandleIterator<Tr>
459 ArrayHandleIterator<Tr>::operator+(typename ArrayHandleIterator<Tr>::difference_type rhs) const
460 {
461 return ArrayHandleIterator<Tr>(pos_ + rhs);
462 }
463
464 template <class Tr>
465 inline const ArrayHandleIterator<Tr>
466 ArrayHandleIterator<Tr>::operator-(typename ArrayHandleIterator<Tr>::difference_type rhs) const
467 {
468 return ArrayHandleIterator<Tr>(pos_ - rhs);
469 }
470
471 template <class Tr>
472 inline typename ArrayHandleIterator<Tr>::difference_type
473 ArrayHandleIterator<Tr>::operator-(const ArrayHandleIterator<Tr>& rhs) const
474 {
475 return (pos_ - rhs.pos_);
476 }
477
478 template <class Tr>
479 inline bool
480 ArrayHandleIterator<Tr>::operator==(const ArrayHandleIterator<Tr>& rhs) const
481 {
482 return (pos_ == rhs.pos_);
483 }
484
485 template <class Tr>
486 inline bool
487 ArrayHandleIterator<Tr>::operator!=(const ArrayHandleIterator<Tr>& rhs) const
488 {
489 return (pos_ != rhs.pos_);
490 }
491
492 template <class Tr>
493 inline bool
494 ArrayHandleIterator<Tr>::operator<(const ArrayHandleIterator<Tr>& rhs) const
495 {
496 return (pos_ < rhs.pos_);
497 }
498
499 template <class Tr>
500 inline bool
501 ArrayHandleIterator<Tr>::operator>(const ArrayHandleIterator<Tr>& rhs) const
502 {
503 return (pos_ > rhs.pos_);
504 }
505
506 template <class Tr>
507 inline bool
508 ArrayHandleIterator<Tr>::operator<=(const ArrayHandleIterator<Tr>& rhs) const
509 {
510 return (pos_ <= rhs.pos_);
511 }
512
513 template <class Tr>
514 inline bool
515 ArrayHandleIterator<Tr>::operator>=(const ArrayHandleIterator<Tr>& rhs) const
516 {
517 return (pos_ >= rhs.pos_);
518 }
519
520 } // namespace Container_Helpers
521
522 /**** Glib::ArrayHandle<> **************************************************/
523
524 template <class T, class Tr>
525 template <class Cont>
526 inline ArrayHandle<T, Tr>::ArrayHandle(const Cont& container)
527 : size_(Glib::Container_Helpers::ArraySourceTraits<Tr, Cont>::get_size(container)),
528 parray_(Glib::Container_Helpers::ArraySourceTraits<Tr, Cont>::get_data(container, size_)),
529 ownership_(Glib::Container_Helpers::ArraySourceTraits<Tr, Cont>::initial_ownership)
530 {
531 }
532
533 template <class T, class Tr>
534 inline ArrayHandle<T, Tr>::ArrayHandle(const typename ArrayHandle<T, Tr>::CType* array,
535 std::size_t array_size, Glib::OwnershipType ownership)
536 : size_((array) ? array_size : 0), parray_(array), ownership_(ownership)
537 {
538 }
539
540 template <class T, class Tr>
541 inline ArrayHandle<T, Tr>::ArrayHandle(
542 const typename ArrayHandle<T, Tr>::CType* array, Glib::OwnershipType ownership)
543 : size_((array) ? Glib::Container_Helpers::compute_array_size(array) : 0),
544 parray_(array),
545 ownership_(ownership)
546 {
547 }
548
549 template <class T, class Tr>
550 inline ArrayHandle<T, Tr>::ArrayHandle(const ArrayHandle<T, Tr>& other)
551 : size_(other.size_), parray_(other.parray_), ownership_(other.ownership_)
552 {
553 other.ownership_ = Glib::OWNERSHIP_NONE;
554 }
555
556 template <class T, class Tr>
557 ArrayHandle<T, Tr>::~ArrayHandle() noexcept
558 {
559 if (parray_ && ownership_ != Glib::OWNERSHIP_NONE)
560 {
561 if (ownership_ != Glib::OWNERSHIP_SHALLOW)
562 {
563 // Deep ownership: release each container element.
564 const CType* const pend = parray_ + size_;
565 for (const CType* p = parray_; p != pend; ++p)
566 Tr::release_c_type(*p);
567 }
568 g_free(const_cast<CType*>(parray_));
569 }
570 }
571
572 template <class T, class Tr>
573 inline typename ArrayHandle<T, Tr>::const_iterator
574 ArrayHandle<T, Tr>::begin() const
575 {
576 return Glib::Container_Helpers::ArrayHandleIterator<Tr>(parray_);
577 }
578
579 template <class T, class Tr>
580 inline typename ArrayHandle<T, Tr>::const_iterator
581 ArrayHandle<T, Tr>::end() const
582 {
583 return Glib::Container_Helpers::ArrayHandleIterator<Tr>(parray_ + size_);
584 }
585
586 template <class T, class Tr>
587 template <class U>
588 inline ArrayHandle<T, Tr>::operator std::vector<U>() const
589 {
590 #ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
591 return std::vector<U>(this->begin(), this->end());
592 #else
593 std::vector<U> temp;
594 temp.reserve(this->size());
595 Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
596 return temp;
597 #endif
598 }
599
600 template <class T, class Tr>
601 template <class U>
602 inline ArrayHandle<T, Tr>::operator std::deque<U>() const
603 {
604 #ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
605 return std::deque<U>(this->begin(), this->end());
606 #else
607 std::deque<U> temp;
608 Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
609 return temp;
610 #endif
611 }
612
613 template <class T, class Tr>
614 template <class U>
615 inline ArrayHandle<T, Tr>::operator std::list<U>() const
616 {
617 #ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
618 return std::list<U>(this->begin(), this->end());
619 #else
620 std::list<U> temp;
621 Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
622 return temp;
623 #endif
624 }
625
626 template <class T, class Tr>
627 template <class Cont>
628 inline void
629 ArrayHandle<T, Tr>::assign_to(Cont& container) const
630 {
631 #ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
632 container.assign(this->begin(), this->end());
633 #else
634 Cont temp;
635 Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
636 container.swap(temp);
637 #endif
638 }
639
640 template <class T, class Tr>
641 template <class Out>
642 inline void
643 ArrayHandle<T, Tr>::copy(Out pdest) const
644 {
645 std::copy(this->begin(), this->end(), pdest);
646 }
647
648 template <class T, class Tr>
649 inline const typename ArrayHandle<T, Tr>::CType*
650 ArrayHandle<T, Tr>::data() const
651 {
652 return parray_;
653 }
654
655 template <class T, class Tr>
656 inline std::size_t
657 ArrayHandle<T, Tr>::size() const
658 {
659 return size_;
660 }
661
662 template <class T, class Tr>
663 inline bool
664 ArrayHandle<T, Tr>::empty() const
665 {
666 return (size_ == 0);
667 }
668
669 /**** Glib::ArrayHandle<bool> **********************************************/
670
671 template <class Cont>
672 inline ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>::ArrayHandle(const Cont& container)
673 : size_(Glib::Container_Helpers::BoolArraySourceTraits<Cont>::get_size(container)),
674 parray_(Glib::Container_Helpers::BoolArraySourceTraits<Cont>::get_data(container, size_)),
675 ownership_(Glib::Container_Helpers::BoolArraySourceTraits<Cont>::initial_ownership)
676 {
677 }
678
679 inline ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>::ArrayHandle(
680 const gboolean* array, std::size_t array_size, Glib::OwnershipType ownership)
681 : size_((array) ? array_size : 0), parray_(array), ownership_(ownership)
682 {
683 }
684
685 inline ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>::ArrayHandle(
686 const gboolean* array, Glib::OwnershipType ownership)
687 : size_((array) ? Glib::Container_Helpers::compute_array_size(array) : 0),
688 parray_(array),
689 ownership_(ownership)
690 {
691 }
692
693 inline ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>::ArrayHandle(
694 const ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>& other)
695 : size_(other.size_), parray_(other.parray_), ownership_(other.ownership_)
696 {
697 other.ownership_ = Glib::OWNERSHIP_NONE;
698 }
699
700 inline ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>::const_iterator
701 ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>::begin() const
702 {
703 return Glib::Container_Helpers::ArrayHandleIterator<Tr>(parray_);
704 }
705
706 inline ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>::const_iterator
707 ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>::end() const
708 {
709 return Glib::Container_Helpers::ArrayHandleIterator<Tr>(parray_ + size_);
710 }
711
712 template <class Cont>
713 inline void
714 ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>::assign_to(Cont& container) const
715 {
716 #ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
717 container.assign(this->begin(), this->end());
718 #else
719 Cont temp;
720 Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
721 container.swap(temp);
722 #endif
723 }
724
725 template <class Out>
726 inline void
727 ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>::copy(Out pdest) const
728 {
729 std::copy(this->begin(), this->end(), pdest);
730 }
731
732 inline const gboolean*
733 ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>::data() const
734 {
735 return parray_;
736 }
737
738 inline std::size_t
739 ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>::size() const
740 {
741 return size_;
742 }
743
744 inline bool
745 ArrayHandle<bool, Container_Helpers::TypeTraits<bool>>::empty() const
746 {
747 return (size_ == 0);
748 }
749
750 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
751
752 } // namespace Glib
753
754 #endif /* _GLIBMM_ARRAYHANDLE_H */
755