1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
5 // Permission to copy, use, modify, sell and distribute this software
6 // is granted provided this copyright notice appears in all copies.
7 // This software is provided "as is" without express or implied
8 // warranty, and with no claim as to its suitability for any purpose.
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 // mcseemagg@yahoo.com
13 // http://www.antigrain.com
14 //----------------------------------------------------------------------------
15 #ifndef AGG_ARRAY_INCLUDED
16 #define AGG_ARRAY_INCLUDED
20 #include "agg_basics.h"
25 //-------------------------------------------------------pod_array_adaptor
26 template<class T
> class pod_array_adaptor
30 pod_array_adaptor(T
* array
, unsigned size
) :
31 m_array(array
), m_size(size
) {}
33 unsigned size() const { return m_size
; }
34 const T
& operator [] (unsigned i
) const { return m_array
[i
]; }
35 T
& operator [] (unsigned i
) { return m_array
[i
]; }
36 const T
& at(unsigned i
) const { return m_array
[i
]; }
37 T
& at(unsigned i
) { return m_array
[i
]; }
38 T
value_at(unsigned i
) const { return m_array
[i
]; }
46 //---------------------------------------------------------pod_auto_array
47 template<class T
, unsigned Size
> class pod_auto_array
51 typedef pod_auto_array
<T
, Size
> self_type
;
54 explicit pod_auto_array(const T
* c
)
56 memcpy(m_array
, c
, sizeof(T
) * Size
);
59 const self_type
& operator = (const T
* c
)
61 memcpy(m_array
, c
, sizeof(T
) * Size
);
65 static unsigned size() { return Size
; }
66 const T
& operator [] (unsigned i
) const { return m_array
[i
]; }
67 T
& operator [] (unsigned i
) { return m_array
[i
]; }
68 const T
& at(unsigned i
) const { return m_array
[i
]; }
69 T
& at(unsigned i
) { return m_array
[i
]; }
70 T
value_at(unsigned i
) const { return m_array
[i
]; }
77 //--------------------------------------------------------pod_auto_vector
78 template<class T
, unsigned Size
> class pod_auto_vector
82 typedef pod_auto_vector
<T
, Size
> self_type
;
84 pod_auto_vector() : m_size(0) {}
86 void remove_all() { m_size
= 0; }
87 void clear() { m_size
= 0; }
88 void add(const T
& v
) { m_array
[m_size
++] = v
; }
89 void push_back(const T
& v
) { m_array
[m_size
++] = v
; }
90 void inc_size(unsigned size
) { m_size
+= size
; }
92 unsigned size() const { return m_size
; }
93 const T
& operator [] (unsigned i
) const { return m_array
[i
]; }
94 T
& operator [] (unsigned i
) { return m_array
[i
]; }
95 const T
& at(unsigned i
) const { return m_array
[i
]; }
96 T
& at(unsigned i
) { return m_array
[i
]; }
97 T
value_at(unsigned i
) const { return m_array
[i
]; }
105 //---------------------------------------------------------------pod_array
106 template<class T
> class pod_array
109 typedef T value_type
;
110 typedef pod_array
<T
> self_type
;
112 ~pod_array() { pod_allocator
<T
>::deallocate(m_array
, m_size
); }
113 pod_array() : m_array(0), m_size(0) {}
115 pod_array(unsigned size
) :
116 m_array(pod_allocator
<T
>::allocate(size
)),
120 pod_array(const self_type
& v
) :
121 m_array(pod_allocator
<T
>::allocate(v
.m_size
)),
124 memcpy(m_array
, v
.m_array
, sizeof(T
) * m_size
);
127 void resize(unsigned size
)
131 pod_allocator
<T
>::deallocate(m_array
, m_size
);
132 m_array
= pod_allocator
<T
>::allocate(m_size
= size
);
135 const self_type
& operator = (const self_type
& v
)
138 memcpy(m_array
, v
.m_array
, sizeof(T
) * m_size
);
142 unsigned size() const { return m_size
; }
143 const T
& operator [] (unsigned i
) const { return m_array
[i
]; }
144 T
& operator [] (unsigned i
) { return m_array
[i
]; }
145 const T
& at(unsigned i
) const { return m_array
[i
]; }
146 T
& at(unsigned i
) { return m_array
[i
]; }
147 T
value_at(unsigned i
) const { return m_array
[i
]; }
149 const T
* data() const { return m_array
; }
150 T
* data() { return m_array
; }
158 //--------------------------------------------------------------pod_vector
159 // A simple class template to store Plain Old Data, a vector
160 // of a fixed size. The data is continous in memory
161 //------------------------------------------------------------------------
162 template<class T
> class pod_vector
165 typedef T value_type
;
167 ~pod_vector() { pod_allocator
<T
>::deallocate(m_array
, m_capacity
); }
168 pod_vector() : m_size(0), m_capacity(0), m_array(0) {}
169 pod_vector(unsigned cap
, unsigned extra_tail
=0);
172 pod_vector(const pod_vector
<T
>&);
173 const pod_vector
<T
>& operator = (const pod_vector
<T
>&);
175 // Set new capacity. All data is lost, size is set to zero.
176 void capacity(unsigned cap
, unsigned extra_tail
=0);
177 unsigned capacity() const { return m_capacity
; }
179 // Allocate n elements. All data is lost,
180 // but elements can be accessed in range 0...size-1.
181 void allocate(unsigned size
, unsigned extra_tail
=0);
183 // Resize keeping the content.
184 void resize(unsigned new_size
);
188 memset(m_array
, 0, sizeof(T
) * m_size
);
191 void add(const T
& v
) { m_array
[m_size
++] = v
; }
192 void push_back(const T
& v
) { m_array
[m_size
++] = v
; }
193 void insert_at(unsigned pos
, const T
& val
);
194 void inc_size(unsigned size
) { m_size
+= size
; }
195 unsigned size() const { return m_size
; }
196 unsigned byte_size() const { return m_size
* sizeof(T
); }
197 void serialize(int8u
* ptr
) const;
198 void deserialize(const int8u
* data
, unsigned byte_size
);
199 const T
& operator [] (unsigned i
) const { return m_array
[i
]; }
200 T
& operator [] (unsigned i
) { return m_array
[i
]; }
201 const T
& at(unsigned i
) const { return m_array
[i
]; }
202 T
& at(unsigned i
) { return m_array
[i
]; }
203 T
value_at(unsigned i
) const { return m_array
[i
]; }
205 const T
* data() const { return m_array
; }
206 T
* data() { return m_array
; }
208 void remove_all() { m_size
= 0; }
209 void clear() { m_size
= 0; }
210 void cut_at(unsigned num
) { if(num
< m_size
) m_size
= num
; }
218 //------------------------------------------------------------------------
220 void pod_vector
<T
>::capacity(unsigned cap
, unsigned extra_tail
)
225 pod_allocator
<T
>::deallocate(m_array
, m_capacity
);
226 m_capacity
= cap
+ extra_tail
;
227 m_array
= m_capacity
? pod_allocator
<T
>::allocate(m_capacity
) : 0;
231 //------------------------------------------------------------------------
233 void pod_vector
<T
>::allocate(unsigned size
, unsigned extra_tail
)
235 capacity(size
, extra_tail
);
240 //------------------------------------------------------------------------
242 void pod_vector
<T
>::resize(unsigned new_size
)
244 if(new_size
> m_size
)
246 if(new_size
> m_capacity
)
248 T
* data
= pod_allocator
<T
>::allocate(new_size
);
249 memcpy(data
, m_array
, m_size
* sizeof(T
));
250 pod_allocator
<T
>::deallocate(m_array
, m_capacity
);
260 //------------------------------------------------------------------------
261 template<class T
> pod_vector
<T
>::pod_vector(unsigned cap
, unsigned extra_tail
) :
263 m_capacity(cap
+ extra_tail
),
264 m_array(pod_allocator
<T
>::allocate(m_capacity
)) {}
266 //------------------------------------------------------------------------
267 template<class T
> pod_vector
<T
>::pod_vector(const pod_vector
<T
>& v
) :
269 m_capacity(v
.m_capacity
),
270 m_array(v
.m_capacity
? pod_allocator
<T
>::allocate(v
.m_capacity
) : 0)
272 memcpy(m_array
, v
.m_array
, sizeof(T
) * v
.m_size
);
275 //------------------------------------------------------------------------
276 template<class T
> const pod_vector
<T
>&
277 pod_vector
<T
>::operator = (const pod_vector
<T
>&v
)
280 if(v
.m_size
) memcpy(m_array
, v
.m_array
, sizeof(T
) * v
.m_size
);
284 //------------------------------------------------------------------------
285 template<class T
> void pod_vector
<T
>::serialize(int8u
* ptr
) const
287 if(m_size
) memcpy(ptr
, m_array
, m_size
* sizeof(T
));
290 //------------------------------------------------------------------------
292 void pod_vector
<T
>::deserialize(const int8u
* data
, unsigned byte_size
)
294 byte_size
/= sizeof(T
);
296 if(byte_size
) memcpy(m_array
, data
, byte_size
* sizeof(T
));
299 //------------------------------------------------------------------------
301 void pod_vector
<T
>::insert_at(unsigned pos
, const T
& val
)
305 m_array
[m_size
] = val
;
309 memmove(m_array
+ pos
+ 1, m_array
+ pos
, (m_size
- pos
) * sizeof(T
));
315 //---------------------------------------------------------------pod_bvector
316 // A simple class template to store Plain Old Data, similar to std::deque
317 // It doesn't reallocate memory but instead, uses blocks of data of size
318 // of (1 << S), that is, power of two. The data is NOT contiguous in memory,
319 // so the only valid access method is operator [] or curr(), prev(), next()
321 // There reallocs occure only when the pool of pointers to blocks needs
322 // to be extended (it happens very rarely). You can control the value
323 // of increment to reallocate the pointer buffer. See the second constructor.
324 // By default, the incremeent value equals (1 << S), i.e., the block size.
325 //------------------------------------------------------------------------
326 template<class T
, unsigned S
=6> class pod_bvector
332 block_size
= 1 << block_shift
,
333 block_mask
= block_size
- 1
336 typedef T value_type
;
340 pod_bvector(unsigned block_ptr_inc
);
343 pod_bvector(const pod_bvector
<T
, S
>& v
);
344 const pod_bvector
<T
, S
>& operator = (const pod_bvector
<T
, S
>& v
);
346 void remove_all() { m_size
= 0; }
347 void clear() { m_size
= 0; }
348 void free_all() { free_tail(0); }
349 void free_tail(unsigned size
);
350 void add(const T
& val
);
351 void push_back(const T
& val
) { add(val
); }
352 void modify_last(const T
& val
);
355 int allocate_continuous_block(unsigned num_elements
);
357 void add_array(const T
* ptr
, unsigned num_elem
)
365 template<class DataAccessor
> void add_data(DataAccessor
& data
)
374 void cut_at(unsigned size
)
376 if(size
< m_size
) m_size
= size
;
379 unsigned size() const { return m_size
; }
381 const T
& operator [] (unsigned i
) const
383 return m_blocks
[i
>> block_shift
][i
& block_mask
];
386 T
& operator [] (unsigned i
)
388 return m_blocks
[i
>> block_shift
][i
& block_mask
];
391 const T
& at(unsigned i
) const
393 return m_blocks
[i
>> block_shift
][i
& block_mask
];
398 return m_blocks
[i
>> block_shift
][i
& block_mask
];
401 T
value_at(unsigned i
) const
403 return m_blocks
[i
>> block_shift
][i
& block_mask
];
406 const T
& curr(unsigned idx
) const
411 T
& curr(unsigned idx
)
416 const T
& prev(unsigned idx
) const
418 return (*this)[(idx
+ m_size
- 1) % m_size
];
421 T
& prev(unsigned idx
)
423 return (*this)[(idx
+ m_size
- 1) % m_size
];
426 const T
& next(unsigned idx
) const
428 return (*this)[(idx
+ 1) % m_size
];
431 T
& next(unsigned idx
)
433 return (*this)[(idx
+ 1) % m_size
];
436 const T
& last() const
438 return (*this)[m_size
- 1];
443 return (*this)[m_size
- 1];
446 unsigned byte_size() const;
447 void serialize(int8u
* ptr
) const;
448 void deserialize(const int8u
* data
, unsigned byte_size
);
449 void deserialize(unsigned start
, const T
& empty_val
,
450 const int8u
* data
, unsigned byte_size
);
452 template<class ByteAccessor
>
453 void deserialize(ByteAccessor data
)
456 unsigned elem_size
= data
.size() / sizeof(T
);
458 for(unsigned i
= 0; i
< elem_size
; ++i
)
460 int8u
* ptr
= (int8u
*)data_ptr();
461 for(unsigned j
= 0; j
< sizeof(T
); ++j
)
470 template<class ByteAccessor
>
471 void deserialize(unsigned start
, const T
& empty_val
, ByteAccessor data
)
473 while(m_size
< start
)
478 unsigned elem_size
= data
.size() / sizeof(T
);
479 for(unsigned i
= 0; i
< elem_size
; ++i
)
482 if(start
+ i
< m_size
)
484 ptr
= (int8u
*)(&((*this)[start
+ i
]));
488 ptr
= (int8u
*)data_ptr();
491 for(unsigned j
= 0; j
< sizeof(T
); ++j
)
499 const T
* block(unsigned nb
) const { return m_blocks
[nb
]; }
502 void allocate_block(unsigned nb
);
506 unsigned m_num_blocks
;
507 unsigned m_max_blocks
;
509 unsigned m_block_ptr_inc
;
513 //------------------------------------------------------------------------
514 template<class T
, unsigned S
> pod_bvector
<T
, S
>::~pod_bvector()
518 T
** blk
= m_blocks
+ m_num_blocks
- 1;
519 while(m_num_blocks
--)
521 pod_allocator
<T
>::deallocate(*blk
, block_size
);
525 pod_allocator
<T
*>::deallocate(m_blocks
, m_max_blocks
);
529 //------------------------------------------------------------------------
530 template<class T
, unsigned S
>
531 void pod_bvector
<T
, S
>::free_tail(unsigned size
)
535 unsigned nb
= (size
+ block_mask
) >> block_shift
;
536 while(m_num_blocks
> nb
)
538 pod_allocator
<T
>::deallocate(m_blocks
[--m_num_blocks
], block_size
);
540 if(m_num_blocks
== 0)
542 pod_allocator
<T
*>::deallocate(m_blocks
, m_max_blocks
);
551 //------------------------------------------------------------------------
552 template<class T
, unsigned S
> pod_bvector
<T
, S
>::pod_bvector() :
557 m_block_ptr_inc(block_size
)
562 //------------------------------------------------------------------------
563 template<class T
, unsigned S
>
564 pod_bvector
<T
, S
>::pod_bvector(unsigned block_ptr_inc
) :
569 m_block_ptr_inc(block_ptr_inc
)
574 //------------------------------------------------------------------------
575 template<class T
, unsigned S
>
576 pod_bvector
<T
, S
>::pod_bvector(const pod_bvector
<T
, S
>& v
) :
578 m_num_blocks(v
.m_num_blocks
),
579 m_max_blocks(v
.m_max_blocks
),
580 m_blocks(v
.m_max_blocks
?
581 pod_allocator
<T
*>::allocate(v
.m_max_blocks
) :
583 m_block_ptr_inc(v
.m_block_ptr_inc
)
586 for(i
= 0; i
< v
.m_num_blocks
; ++i
)
588 m_blocks
[i
] = pod_allocator
<T
>::allocate(block_size
);
589 memcpy(m_blocks
[i
], v
.m_blocks
[i
], block_size
* sizeof(T
));
594 //------------------------------------------------------------------------
595 template<class T
, unsigned S
>
596 const pod_bvector
<T
, S
>&
597 pod_bvector
<T
, S
>::operator = (const pod_bvector
<T
, S
>& v
)
600 for(i
= m_num_blocks
; i
< v
.m_num_blocks
; ++i
)
604 for(i
= 0; i
< v
.m_num_blocks
; ++i
)
606 memcpy(m_blocks
[i
], v
.m_blocks
[i
], block_size
* sizeof(T
));
613 //------------------------------------------------------------------------
614 template<class T
, unsigned S
>
615 void pod_bvector
<T
, S
>::allocate_block(unsigned nb
)
617 if(nb
>= m_max_blocks
)
619 T
** new_blocks
= pod_allocator
<T
*>::allocate(m_max_blocks
+ m_block_ptr_inc
);
625 m_num_blocks
* sizeof(T
*));
627 pod_allocator
<T
*>::deallocate(m_blocks
, m_max_blocks
);
629 m_blocks
= new_blocks
;
630 m_max_blocks
+= m_block_ptr_inc
;
632 m_blocks
[nb
] = pod_allocator
<T
>::allocate(block_size
);
638 //------------------------------------------------------------------------
639 template<class T
, unsigned S
>
640 inline T
* pod_bvector
<T
, S
>::data_ptr()
642 unsigned nb
= m_size
>> block_shift
;
643 if(nb
>= m_num_blocks
)
647 return m_blocks
[nb
] + (m_size
& block_mask
);
652 //------------------------------------------------------------------------
653 template<class T
, unsigned S
>
654 inline void pod_bvector
<T
, S
>::add(const T
& val
)
661 //------------------------------------------------------------------------
662 template<class T
, unsigned S
>
663 inline void pod_bvector
<T
, S
>::remove_last()
669 //------------------------------------------------------------------------
670 template<class T
, unsigned S
>
671 void pod_bvector
<T
, S
>::modify_last(const T
& val
)
678 //------------------------------------------------------------------------
679 template<class T
, unsigned S
>
680 int pod_bvector
<T
, S
>::allocate_continuous_block(unsigned num_elements
)
682 if(num_elements
< block_size
)
684 data_ptr(); // Allocate initial block if necessary
685 unsigned rest
= block_size
- (m_size
& block_mask
);
687 if(num_elements
<= rest
)
689 // The rest of the block is good, we can use it
692 m_size
+= num_elements
;
701 m_size
+= num_elements
;
704 return -1; // Impossible to allocate
708 //------------------------------------------------------------------------
709 template<class T
, unsigned S
>
710 unsigned pod_bvector
<T
, S
>::byte_size() const
712 return m_size
* sizeof(T
);
716 //------------------------------------------------------------------------
717 template<class T
, unsigned S
>
718 void pod_bvector
<T
, S
>::serialize(int8u
* ptr
) const
721 for(i
= 0; i
< m_size
; i
++)
723 memcpy(ptr
, &(*this)[i
], sizeof(T
));
728 //------------------------------------------------------------------------
729 template<class T
, unsigned S
>
730 void pod_bvector
<T
, S
>::deserialize(const int8u
* data
, unsigned byte_size
)
733 byte_size
/= sizeof(T
);
734 for(unsigned i
= 0; i
< byte_size
; ++i
)
737 memcpy(ptr
, data
, sizeof(T
));
744 // Replace or add a number of elements starting from "start" position
745 //------------------------------------------------------------------------
746 template<class T
, unsigned S
>
747 void pod_bvector
<T
, S
>::deserialize(unsigned start
, const T
& empty_val
,
748 const int8u
* data
, unsigned byte_size
)
750 while(m_size
< start
)
755 byte_size
/= sizeof(T
);
756 for(unsigned i
= 0; i
< byte_size
; ++i
)
758 if(start
+ i
< m_size
)
760 memcpy(&((*this)[start
+ i
]), data
, sizeof(T
));
765 memcpy(ptr
, data
, sizeof(T
));
773 //---------------------------------------------------------block_allocator
774 // Allocator for arbitrary POD data. Most usable in different cache
775 // systems for efficient memory allocations.
776 // Memory is allocated with blocks of fixed size ("block_size" in
777 // the constructor). If required size exceeds the block size the allocator
778 // creates a new block of the required size. However, the most efficient
779 // use is when the average reqired size is much less than the block size.
780 //------------------------------------------------------------------------
781 class block_allocator
794 block_type
* blk
= m_blocks
+ m_num_blocks
- 1;
795 while(m_num_blocks
--)
797 pod_allocator
<int8u
>::deallocate(blk
->data
, blk
->size
);
800 pod_allocator
<block_type
>::deallocate(m_blocks
, m_max_blocks
);
814 block_allocator(unsigned block_size
, unsigned block_ptr_inc
=256-8) :
815 m_block_size(block_size
),
816 m_block_ptr_inc(block_ptr_inc
),
826 int8u
* allocate(unsigned size
, unsigned alignment
=1)
828 if(size
== 0) return 0;
831 int8u
* ptr
= m_buf_ptr
;
835 (alignment
- unsigned((size_t)ptr
) % alignment
) % alignment
;
845 allocate_block(size
);
846 return allocate(size
- align
, alignment
);
852 allocate_block(size
+ alignment
- 1);
853 return allocate(size
, alignment
);
858 void allocate_block(unsigned size
)
860 if(size
< m_block_size
) size
= m_block_size
;
861 if(m_num_blocks
>= m_max_blocks
)
863 block_type
* new_blocks
=
864 pod_allocator
<block_type
>::allocate(m_max_blocks
+ m_block_ptr_inc
);
870 m_num_blocks
* sizeof(block_type
));
871 pod_allocator
<block_type
>::deallocate(m_blocks
, m_max_blocks
);
873 m_blocks
= new_blocks
;
874 m_max_blocks
+= m_block_ptr_inc
;
877 m_blocks
[m_num_blocks
].size
= size
;
878 m_blocks
[m_num_blocks
].data
=
880 pod_allocator
<int8u
>::allocate(size
);
886 unsigned m_block_size
;
887 unsigned m_block_ptr_inc
;
888 unsigned m_num_blocks
;
889 unsigned m_max_blocks
;
890 block_type
* m_blocks
;
902 //------------------------------------------------------------------------
903 enum quick_sort_threshold_e
905 quick_sort_threshold
= 9
909 //-----------------------------------------------------------swap_elements
910 template<class T
> inline void swap_elements(T
& a
, T
& b
)
918 //--------------------------------------------------------------quick_sort
919 template<class Array
, class Less
>
920 void quick_sort(Array
& arr
, Less less
)
922 if(arr
.size() < 2) return;
924 typename
Array::value_type
* e1
;
925 typename
Array::value_type
* e2
;
929 int limit
= arr
.size();
934 int len
= limit
- base
;
940 if(len
> quick_sort_threshold
)
942 // we use base + len/2 as the pivot
943 pivot
= base
+ len
/ 2;
944 swap_elements(arr
[base
], arr
[pivot
]);
949 // now ensure that *i <= *base <= *j
952 if(less(*e1
, *e2
)) swap_elements(*e1
, *e2
);
956 if(less(*e1
, *e2
)) swap_elements(*e1
, *e2
);
960 if(less(*e1
, *e2
)) swap_elements(*e1
, *e2
);
964 do i
++; while( less(arr
[i
], arr
[base
]) );
965 do j
--; while( less(arr
[base
], arr
[j
]) );
972 swap_elements(arr
[i
], arr
[j
]);
975 swap_elements(arr
[base
], arr
[j
]);
977 // now, push the largest sub-array
978 if(j
- base
> limit
- i
)
994 // the sub-array is small, perform insertion sort
998 for(; i
< limit
; j
= i
, i
++)
1000 for(; less(*(e1
= &(arr
[j
+ 1])), *(e2
= &(arr
[j
]))); j
--)
1002 swap_elements(*e1
, *e2
);
1026 //------------------------------------------------------remove_duplicates
1027 // Remove duplicates from a sorted array. It doesn't cut the
1028 // tail of the array, it just returns the number of remaining elements.
1029 //-----------------------------------------------------------------------
1030 template<class Array
, class Equal
>
1031 unsigned remove_duplicates(Array
& arr
, Equal equal
)
1033 if(arr
.size() < 2) return arr
.size();
1036 for(i
= 1, j
= 1; i
< arr
.size(); i
++)
1038 typename
Array::value_type
& e
= arr
[i
];
1039 if(!equal(e
, arr
[i
- 1]))
1047 //--------------------------------------------------------invert_container
1048 template<class Array
> void invert_container(Array
& arr
)
1051 int j
= arr
.size() - 1;
1054 swap_elements(arr
[i
++], arr
[j
--]);
1058 //------------------------------------------------------binary_search_pos
1059 template<class Array
, class Value
, class Less
>
1060 unsigned binary_search_pos(const Array
& arr
, const Value
& val
, Less less
)
1062 if(arr
.size() == 0) return 0;
1065 unsigned end
= arr
.size() - 1;
1067 if(less(val
, arr
[0])) return 0;
1068 if(less(arr
[end
], val
)) return end
+ 1;
1070 while(end
- beg
> 1)
1072 unsigned mid
= (end
+ beg
) >> 1;
1073 if(less(val
, arr
[mid
])) end
= mid
;
1077 //if(beg <= 0 && less(val, arr[0])) return 0;
1078 //if(end >= arr.size() - 1 && less(arr[end], val)) ++end;
1083 //----------------------------------------------------------range_adaptor
1084 template<class Array
> class range_adaptor
1087 typedef typename
Array::value_type value_type
;
1089 range_adaptor(Array
& array
, unsigned start
, unsigned size
) :
1090 m_array(array
), m_start(start
), m_size(size
)
1093 unsigned size() const { return m_size
; }
1094 const value_type
& operator [] (unsigned i
) const { return m_array
[m_start
+ i
]; }
1095 value_type
& operator [] (unsigned i
) { return m_array
[m_start
+ i
]; }
1096 const value_type
& at(unsigned i
) const { return m_array
[m_start
+ i
]; }
1097 value_type
& at(unsigned i
) { return m_array
[m_start
+ i
]; }
1098 value_type
value_at(unsigned i
) const { return m_array
[m_start
+ i
]; }
1106 //---------------------------------------------------------------int_less
1107 inline bool int_less(int a
, int b
) { return a
< b
; }
1109 //------------------------------------------------------------int_greater
1110 inline bool int_greater(int a
, int b
) { return a
> b
; }
1112 //----------------------------------------------------------unsigned_less
1113 inline bool unsigned_less(unsigned a
, unsigned b
) { return a
< b
; }
1115 //-------------------------------------------------------unsigned_greater
1116 inline bool unsigned_greater(unsigned a
, unsigned b
) { return a
> b
; }