1 /* Copyright (c) 2003-2006, 2008 MySQL AB
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
19 #include <ndb_global.h>
22 * Bitmask implementation. Size is given explicitly
23 * (as first argument). All methods are static.
27 STATIC_CONST( NotFound
= (unsigned)-1 );
30 * get - Check if bit n is set.
32 static bool get(unsigned size
, const Uint32 data
[], unsigned n
);
35 * set - Set bit n to given value (true/false).
37 static void set(unsigned size
, Uint32 data
[], unsigned n
, bool value
);
42 static void set(unsigned size
, Uint32 data
[], unsigned n
);
47 static void set(unsigned size
, Uint32 data
[]);
50 * set bit from <em>start</em> to <em>last</em>
52 static void set_range(unsigned size
, Uint32 data
[], unsigned start
, unsigned last
);
55 * assign - Set all bits in <em>dst</em> to corresponding in <em>src/<em>
57 static void assign(unsigned size
, Uint32 dst
[], const Uint32 src
[]);
60 * clear - Clear bit n.
62 static void clear(unsigned size
, Uint32 data
[], unsigned n
);
65 * clear - Clear all bits.
67 static void clear(unsigned size
, Uint32 data
[]);
70 * clear bit from <em>start</em> to <em>last</em>
72 static void clear_range(unsigned size
, Uint32 data
[], unsigned start
, unsigned last
);
74 static Uint32
getWord(unsigned size
, Uint32 data
[], unsigned word_pos
);
75 static void setWord(unsigned size
, Uint32 data
[],
76 unsigned word_pos
, Uint32 new_word
);
78 * isclear - Check if all bits are clear. This is faster
79 * than checking count() == 0.
81 static bool isclear(unsigned size
, const Uint32 data
[]);
84 * count - Count number of set bits.
86 static unsigned count(unsigned size
, const Uint32 data
[]);
89 * find - Find first set bit, starting at given position.
90 * Returns NotFound when not found.
92 static unsigned find(unsigned size
, const Uint32 data
[], unsigned n
);
95 * equal - Bitwise equal.
97 static bool equal(unsigned size
, const Uint32 data
[], const Uint32 data2
[]);
100 * bitOR - Bitwise (x | y) into first operand.
102 static void bitOR(unsigned size
, Uint32 data
[], const Uint32 data2
[]);
105 * bitAND - Bitwise (x & y) into first operand.
107 static void bitAND(unsigned size
, Uint32 data
[], const Uint32 data2
[]);
110 * bitANDC - Bitwise (x & ~y) into first operand.
112 static void bitANDC(unsigned size
, Uint32 data
[], const Uint32 data2
[]);
115 * bitXOR - Bitwise (x ^ y) into first operand.
117 static void bitXOR(unsigned size
, Uint32 data
[], const Uint32 data2
[]);
120 * bitXORC - Bitwise (x ^ ~y) into first operand.
122 static void bitXORC(unsigned size
, Uint32 data
[], const Uint32 data2
[]);
125 * contains - Check if all bits set in data2 are set in data
127 static bool contains(unsigned size
, Uint32 data
[], const Uint32 data2
[]);
130 * overlaps - Check if any bit set in data is set in data2
132 static bool overlaps(unsigned size
, Uint32 data
[], const Uint32 data2
[]);
135 * getField - Get bitfield at given position and length (max 32 bits)
137 static Uint32
getField(unsigned size
, const Uint32 data
[],
138 unsigned pos
, unsigned len
);
141 * setField - Set bitfield at given position and length (max 32 bits)
142 * Note : length == 0 not supported.
144 static void setField(unsigned size
, Uint32 data
[],
145 unsigned pos
, unsigned len
, Uint32 val
);
149 * getField - Get bitfield at given position and length
150 * Note : length == 0 not supported.
152 static void getField(unsigned size
, const Uint32 data
[],
153 unsigned pos
, unsigned len
, Uint32 dst
[]);
156 * setField - Set bitfield at given position and length
158 static void setField(unsigned size
, Uint32 data
[],
159 unsigned pos
, unsigned len
, const Uint32 src
[]);
162 * getText - Return as hex-digits (only for debug routines).
164 static char* getText(unsigned size
, const Uint32 data
[], char* buf
);
166 static void getFieldImpl(const Uint32 data
[], unsigned, unsigned, Uint32
[]);
167 static void setFieldImpl(Uint32 data
[], unsigned, unsigned, const Uint32
[]);
171 BitmaskImpl::get(unsigned size
, const Uint32 data
[], unsigned n
)
173 assert(n
< (size
<< 5));
174 return (data
[n
>> 5] & (1 << (n
& 31))) != 0;
178 BitmaskImpl::set(unsigned size
, Uint32 data
[], unsigned n
, bool value
)
180 value
? set(size
, data
, n
) : clear(size
, data
, n
);
184 BitmaskImpl::set(unsigned size
, Uint32 data
[], unsigned n
)
186 assert(n
< (size
<< 5));
187 data
[n
>> 5] |= (1 << (n
& 31));
191 BitmaskImpl::set(unsigned size
, Uint32 data
[])
193 for (unsigned i
= 0; i
< size
; i
++) {
199 BitmaskImpl::set_range(unsigned size
, Uint32 data
[],
200 unsigned start
, unsigned last
)
202 Uint32
*ptr
= data
+ (start
>> 5);
203 Uint32
*end
= data
+ (last
>> 5);
204 assert(start
<= last
);
205 assert(last
< (size
<< 5));
207 Uint32 tmp_word
= ~(Uint32
)0 << (start
& 31);
211 * ptr
++ |= tmp_word
;
215 * ptr
++ = ~(Uint32
)0;
218 tmp_word
= ~(Uint32
)0;
221 tmp_word
&= ~(~(Uint32
)0 << (last
& 31));
227 BitmaskImpl::assign(unsigned size
, Uint32 dst
[], const Uint32 src
[])
229 for (unsigned i
= 0; i
< size
; i
++) {
235 BitmaskImpl::clear(unsigned size
, Uint32 data
[], unsigned n
)
237 assert(n
< (size
<< 5));
238 data
[n
>> 5] &= ~(1 << (n
& 31));
242 BitmaskImpl::clear(unsigned size
, Uint32 data
[])
244 for (unsigned i
= 0; i
< size
; i
++) {
250 BitmaskImpl::clear_range(unsigned size
, Uint32 data
[],
251 unsigned start
, unsigned last
)
253 Uint32
*ptr
= data
+ (start
>> 5);
254 Uint32
*end
= data
+ (last
>> 5);
255 assert(start
<= last
);
256 assert(last
< (size
<< 5));
258 Uint32 tmp_word
= ~(Uint32
)0 << (start
& 31);
262 * ptr
++ &= ~tmp_word
;
269 tmp_word
= ~(Uint32
)0;
272 tmp_word
&= ~(~(Uint32
)0 << (last
& 31));
279 BitmaskImpl::getWord(unsigned size
, Uint32 data
[], unsigned word_pos
)
281 return data
[word_pos
];
285 BitmaskImpl::setWord(unsigned size
, Uint32 data
[],
286 unsigned word_pos
, Uint32 new_word
)
288 data
[word_pos
] = new_word
;
293 BitmaskImpl::isclear(unsigned size
, const Uint32 data
[])
295 for (unsigned i
= 0; i
< size
; i
++) {
303 BitmaskImpl::count(unsigned size
, const Uint32 data
[])
306 for (unsigned i
= 0; i
< size
; i
++) {
317 BitmaskImpl::find(unsigned size
, const Uint32 data
[], unsigned n
)
319 while (n
< (size
<< 5)) { // XXX make this smarter
320 if (get(size
, data
, n
)) {
329 BitmaskImpl::equal(unsigned size
, const Uint32 data
[], const Uint32 data2
[])
331 for (unsigned i
= 0; i
< size
; i
++) {
332 if (data
[i
] != data2
[i
])
339 BitmaskImpl::bitOR(unsigned size
, Uint32 data
[], const Uint32 data2
[])
341 for (unsigned i
= 0; i
< size
; i
++) {
347 BitmaskImpl::bitAND(unsigned size
, Uint32 data
[], const Uint32 data2
[])
349 for (unsigned i
= 0; i
< size
; i
++) {
355 BitmaskImpl::bitANDC(unsigned size
, Uint32 data
[], const Uint32 data2
[])
357 for (unsigned i
= 0; i
< size
; i
++) {
358 data
[i
] &= ~data2
[i
];
363 BitmaskImpl::bitXOR(unsigned size
, Uint32 data
[], const Uint32 data2
[])
365 for (unsigned i
= 0; i
< size
; i
++) {
371 BitmaskImpl::bitXORC(unsigned size
, Uint32 data
[], const Uint32 data2
[])
373 for (unsigned i
= 0; i
< size
; i
++) {
374 data
[i
] ^= ~data2
[i
];
379 BitmaskImpl::contains(unsigned size
, Uint32 data
[], const Uint32 data2
[])
381 for (unsigned int i
= 0; i
< size
; i
++)
382 if ((data
[i
] & data2
[i
]) != data2
[i
])
388 BitmaskImpl::overlaps(unsigned size
, Uint32 data
[], const Uint32 data2
[])
390 for (unsigned int i
= 0; i
< size
; i
++)
391 if ((data
[i
] & data2
[i
]) != 0)
397 BitmaskImpl::getField(unsigned size
, const Uint32 data
[],
398 unsigned pos
, unsigned len
)
401 for (unsigned i
= 0; i
< len
; i
++)
402 val
|= get(size
, data
, pos
+ i
) << i
;
407 BitmaskImpl::setField(unsigned size
, Uint32 data
[],
408 unsigned pos
, unsigned len
, Uint32 val
)
410 for (unsigned i
= 0; i
< len
; i
++)
411 set(size
, data
, pos
+ i
, val
& (1 << i
));
415 BitmaskImpl::getText(unsigned size
, const Uint32 data
[], char* buf
)
418 const char* const hex
= "0123456789abcdef";
419 for (int i
= (size
-1); i
>= 0; i
--) {
421 for (unsigned j
= 0; j
< 8; j
++) {
422 buf
[7-j
] = hex
[x
& 0xf];
432 * Bitmasks. The size is number of 32-bit words (Uint32).
433 * Unused bits in the last word must be zero.
435 * XXX replace size by length in bits
437 template <unsigned size
>
441 * POD data representation
446 Data
& operator=(const BitmaskPOD
<size
> & src
) {
447 src
.copyto(size
, data
);
456 STATIC_CONST( Size
= size
);
457 STATIC_CONST( NotFound
= BitmaskImpl::NotFound
);
458 STATIC_CONST( TextLength
= size
* 8 );
461 * assign - Set all bits in <em>dst</em> to corresponding in <em>src/<em>
463 void assign(const typename BitmaskPOD
<size
>::Data
& src
);
466 * assign - Set all bits in <em>dst</em> to corresponding in <em>src/<em>
468 static void assign(Uint32 dst
[], const Uint32 src
[]);
469 static void assign(Uint32 dst
[], const BitmaskPOD
<size
> & src
);
470 void assign(const BitmaskPOD
<size
> & src
);
473 * copy this to <em>dst</em>
475 void copyto(unsigned sz
, Uint32 dst
[]) const;
478 * assign <em>this</em> according to <em>src/em>
480 void assign(unsigned sz
, const Uint32 src
[]);
483 * get - Check if bit n is set.
485 static bool get(const Uint32 data
[], unsigned n
);
486 bool get(unsigned n
) const;
489 * set - Set bit n to given value (true/false).
491 static void set(Uint32 data
[], unsigned n
, bool value
);
492 void set(unsigned n
, bool value
);
497 static void set(Uint32 data
[], unsigned n
);
498 void set(unsigned n
);
501 * set - set all bits.
503 static void set(Uint32 data
[]);
507 * clear - Clear bit n.
509 static void clear(Uint32 data
[], unsigned n
);
510 void clear(unsigned n
);
513 * clear - Clear all bits.
515 static void clear(Uint32 data
[]);
519 * Get and set words of bits
521 Uint32
getWord(unsigned word_pos
);
522 void setWord(unsigned word_pos
, Uint32 new_word
);
525 * isclear - Check if all bits are clear. This is faster
526 * than checking count() == 0.
528 static bool isclear(const Uint32 data
[]);
529 bool isclear() const;
532 * count - Count number of set bits.
534 static unsigned count(const Uint32 data
[]);
535 unsigned count() const;
538 * find - Find first set bit, starting at given position.
539 * Returns NotFound when not found.
541 static unsigned find(const Uint32 data
[], unsigned n
);
542 unsigned find(unsigned n
) const;
545 * equal - Bitwise equal.
547 static bool equal(const Uint32 data
[], const Uint32 data2
[]);
548 bool equal(const BitmaskPOD
<size
>& mask2
) const;
551 * bitOR - Bitwise (x | y) into first operand.
553 static void bitOR(Uint32 data
[], const Uint32 data2
[]);
554 BitmaskPOD
<size
>& bitOR(const BitmaskPOD
<size
>& mask2
);
557 * bitAND - Bitwise (x & y) into first operand.
559 static void bitAND(Uint32 data
[], const Uint32 data2
[]);
560 BitmaskPOD
<size
>& bitAND(const BitmaskPOD
<size
>& mask2
);
563 * bitANDC - Bitwise (x & ~y) into first operand.
565 static void bitANDC(Uint32 data
[], const Uint32 data2
[]);
566 BitmaskPOD
<size
>& bitANDC(const BitmaskPOD
<size
>& mask2
);
569 * bitXOR - Bitwise (x ^ y) into first operand.
571 static void bitXOR(Uint32 data
[], const Uint32 data2
[]);
572 BitmaskPOD
<size
>& bitXOR(const BitmaskPOD
<size
>& mask2
);
575 * bitXORC - Bitwise (x ^ ~y) into first operand.
577 static void bitXORC(Uint32 data
[], const Uint32 data2
[]);
578 BitmaskPOD
<size
>& bitXORC(const BitmaskPOD
<size
>& mask2
);
581 * contains - Check if all bits set in data2 (that) are also set in data (this)
583 static bool contains(Uint32 data
[], const Uint32 data2
[]);
584 bool contains(BitmaskPOD
<size
> that
);
587 * overlaps - Check if any bit set in this BitmaskPOD (data) is also set in that (data2)
589 static bool overlaps(Uint32 data
[], const Uint32 data2
[]);
590 bool overlaps(BitmaskPOD
<size
> that
);
593 * getText - Return as hex-digits (only for debug routines).
595 static char* getText(const Uint32 data
[], char* buf
);
596 char* getText(char* buf
) const;
599 template <unsigned size
>
601 BitmaskPOD
<size
>::assign(Uint32 dst
[], const Uint32 src
[])
603 BitmaskImpl::assign(size
, dst
, src
);
606 template <unsigned size
>
608 BitmaskPOD
<size
>::assign(Uint32 dst
[], const BitmaskPOD
<size
> & src
)
610 BitmaskImpl::assign(size
, dst
, src
.rep
.data
);
613 template <unsigned size
>
615 BitmaskPOD
<size
>::assign(const typename BitmaskPOD
<size
>::Data
& src
)
617 BitmaskPOD
<size
>::assign(rep
.data
, src
.data
);
620 template <unsigned size
>
622 BitmaskPOD
<size
>::assign(const BitmaskPOD
<size
> & src
)
624 BitmaskPOD
<size
>::assign(rep
.data
, src
.rep
.data
);
627 template <unsigned size
>
629 BitmaskPOD
<size
>::copyto(unsigned sz
, Uint32 dst
[]) const
631 BitmaskImpl::assign(sz
, dst
, rep
.data
);
634 template <unsigned size
>
636 BitmaskPOD
<size
>::assign(unsigned sz
, const Uint32 src
[])
638 BitmaskImpl::assign(sz
, rep
.data
, src
);
641 template <unsigned size
>
643 BitmaskPOD
<size
>::get(const Uint32 data
[], unsigned n
)
645 return BitmaskImpl::get(size
, data
, n
);
648 template <unsigned size
>
650 BitmaskPOD
<size
>::get(unsigned n
) const
652 return BitmaskPOD
<size
>::get(rep
.data
, n
);
655 template <unsigned size
>
657 BitmaskPOD
<size
>::set(Uint32 data
[], unsigned n
, bool value
)
659 BitmaskImpl::set(size
, data
, n
, value
);
662 template <unsigned size
>
664 BitmaskPOD
<size
>::set(unsigned n
, bool value
)
666 BitmaskPOD
<size
>::set(rep
.data
, n
, value
);
669 template <unsigned size
>
671 BitmaskPOD
<size
>::set(Uint32 data
[], unsigned n
)
673 BitmaskImpl::set(size
, data
, n
);
676 template <unsigned size
>
678 BitmaskPOD
<size
>::set(unsigned n
)
680 BitmaskPOD
<size
>::set(rep
.data
, n
);
683 template <unsigned size
>
685 BitmaskPOD
<size
>::set(Uint32 data
[])
687 BitmaskImpl::set(size
, data
);
690 template <unsigned size
>
692 BitmaskPOD
<size
>::set()
694 BitmaskPOD
<size
>::set(rep
.data
);
697 template <unsigned size
>
699 BitmaskPOD
<size
>::clear(Uint32 data
[], unsigned n
)
701 BitmaskImpl::clear(size
, data
, n
);
704 template <unsigned size
>
706 BitmaskPOD
<size
>::clear(unsigned n
)
708 BitmaskPOD
<size
>::clear(rep
.data
, n
);
711 template <unsigned size
>
713 BitmaskPOD
<size
>::clear(Uint32 data
[])
715 BitmaskImpl::clear(size
, data
);
718 template <unsigned size
>
720 BitmaskPOD
<size
>::clear()
722 BitmaskPOD
<size
>::clear(rep
.data
);
725 template <unsigned size
>
727 BitmaskPOD
<size
>::getWord(unsigned word_pos
)
729 return BitmaskImpl::getWord(size
, rep
.data
, word_pos
);
732 template <unsigned size
>
734 BitmaskPOD
<size
>::setWord(unsigned word_pos
, Uint32 new_word
)
736 BitmaskImpl::setWord(size
, rep
.data
, word_pos
, new_word
);
739 template <unsigned size
>
741 BitmaskPOD
<size
>::isclear(const Uint32 data
[])
743 return BitmaskImpl::isclear(size
, data
);
746 template <unsigned size
>
748 BitmaskPOD
<size
>::isclear() const
750 return BitmaskPOD
<size
>::isclear(rep
.data
);
753 template <unsigned size
>
755 BitmaskPOD
<size
>::count(const Uint32 data
[])
757 return BitmaskImpl::count(size
, data
);
760 template <unsigned size
>
762 BitmaskPOD
<size
>::count() const
764 return BitmaskPOD
<size
>::count(rep
.data
);
767 template <unsigned size
>
769 BitmaskPOD
<size
>::find(const Uint32 data
[], unsigned n
)
771 return BitmaskImpl::find(size
, data
, n
);
774 template <unsigned size
>
776 BitmaskPOD
<size
>::find(unsigned n
) const
778 return BitmaskPOD
<size
>::find(rep
.data
, n
);
781 template <unsigned size
>
783 BitmaskPOD
<size
>::equal(const Uint32 data
[], const Uint32 data2
[])
785 return BitmaskImpl::equal(size
, data
, data2
);
788 template <unsigned size
>
790 BitmaskPOD
<size
>::equal(const BitmaskPOD
<size
>& mask2
) const
792 return BitmaskPOD
<size
>::equal(rep
.data
, mask2
.rep
.data
);
795 template <unsigned size
>
797 BitmaskPOD
<size
>::bitOR(Uint32 data
[], const Uint32 data2
[])
799 BitmaskImpl::bitOR(size
,data
, data2
);
802 template <unsigned size
>
803 inline BitmaskPOD
<size
>&
804 BitmaskPOD
<size
>::bitOR(const BitmaskPOD
<size
>& mask2
)
806 BitmaskPOD
<size
>::bitOR(rep
.data
, mask2
.rep
.data
);
810 template <unsigned size
>
812 BitmaskPOD
<size
>::bitAND(Uint32 data
[], const Uint32 data2
[])
814 BitmaskImpl::bitAND(size
,data
, data2
);
817 template <unsigned size
>
818 inline BitmaskPOD
<size
>&
819 BitmaskPOD
<size
>::bitAND(const BitmaskPOD
<size
>& mask2
)
821 BitmaskPOD
<size
>::bitAND(rep
.data
, mask2
.rep
.data
);
825 template <unsigned size
>
827 BitmaskPOD
<size
>::bitANDC(Uint32 data
[], const Uint32 data2
[])
829 BitmaskImpl::bitANDC(size
,data
, data2
);
832 template <unsigned size
>
833 inline BitmaskPOD
<size
>&
834 BitmaskPOD
<size
>::bitANDC(const BitmaskPOD
<size
>& mask2
)
836 BitmaskPOD
<size
>::bitANDC(rep
.data
, mask2
.rep
.data
);
840 template <unsigned size
>
842 BitmaskPOD
<size
>::bitXOR(Uint32 data
[], const Uint32 data2
[])
844 BitmaskImpl::bitXOR(size
,data
, data2
);
847 template <unsigned size
>
848 inline BitmaskPOD
<size
>&
849 BitmaskPOD
<size
>::bitXOR(const BitmaskPOD
<size
>& mask2
)
851 BitmaskPOD
<size
>::bitXOR(rep
.data
, mask2
.rep
.data
);
855 template <unsigned size
>
857 BitmaskPOD
<size
>::bitXORC(Uint32 data
[], const Uint32 data2
[])
859 BitmaskImpl::bitXORC(size
,data
, data2
);
862 template <unsigned size
>
863 inline BitmaskPOD
<size
>&
864 BitmaskPOD
<size
>::bitXORC(const BitmaskPOD
<size
>& mask2
)
866 BitmaskPOD
<size
>::bitXORC(rep
.data
, mask2
.rep
.data
);
870 template <unsigned size
>
872 BitmaskPOD
<size
>::getText(const Uint32 data
[], char* buf
)
874 return BitmaskImpl::getText(size
, data
, buf
);
877 template <unsigned size
>
879 BitmaskPOD
<size
>::getText(char* buf
) const
881 return BitmaskPOD
<size
>::getText(rep
.data
, buf
);
884 template <unsigned size
>
886 BitmaskPOD
<size
>::contains(Uint32 data
[], const Uint32 data2
[])
888 return BitmaskImpl::contains(size
, data
, data2
);
891 template <unsigned size
>
893 BitmaskPOD
<size
>::contains(BitmaskPOD
<size
> that
)
895 return BitmaskPOD
<size
>::contains(this->rep
.data
, that
.rep
.data
);
898 template <unsigned size
>
900 BitmaskPOD
<size
>::overlaps(Uint32 data
[], const Uint32 data2
[])
902 return BitmaskImpl::overlaps(size
, data
, data2
);
905 template <unsigned size
>
907 BitmaskPOD
<size
>::overlaps(BitmaskPOD
<size
> that
)
909 return BitmaskPOD
<size
>::overlaps(this->rep
.data
, that
.rep
.data
);
912 template <unsigned size
>
913 class Bitmask
: public BitmaskPOD
<size
> {
915 Bitmask() { this->clear();}
919 BitmaskImpl::getField(unsigned size
, const Uint32 src
[],
920 unsigned pos
, unsigned len
, Uint32 dst
[])
922 assert(pos
+ len
<= (size
<< 5));
928 Uint32 offset
= pos
& 31;
929 * dst
= (* src
>> offset
) & (len
>= 32 ? ~0 : (1 << len
) - 1);
931 if(offset
+ len
<= 32)
935 Uint32 used
= (32 - offset
);
937 getFieldImpl(src
+1, used
& 31, len
-used
, dst
+(used
>> 5));
941 BitmaskImpl::setField(unsigned size
, Uint32 dst
[],
942 unsigned pos
, unsigned len
, const Uint32 src
[])
944 assert(pos
+ len
<= (size
<< 5));
950 Uint32 offset
= pos
& 31;
951 Uint32 mask
= (len
>= 32 ? ~0 : (1 << len
) - 1) << offset
;
953 * dst
= (* dst
& ~mask
) | ((*src
<< offset
) & mask
);
955 if(offset
+ len
<= 32)
959 Uint32 used
= (32 - offset
);
961 setFieldImpl(dst
+1, used
& 31, len
-used
, src
+(used
>> 5));