9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_UTILITIES_GROWABLEARRAY_HPP
26 #define SHARE_UTILITIES_GROWABLEARRAY_HPP
27
28 #include "memory/allocation.hpp"
29 #include "memory/iterator.hpp"
30 #include "utilities/debug.hpp"
31 #include "utilities/globalDefinitions.hpp"
32 #include "utilities/ostream.hpp"
33 #include "utilities/powerOfTwo.hpp"
34
35 // A growable array.
36
37 /*************************************************************************/
38 /* */
39 /* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING */
40 /* */
41 /* Should you use GrowableArrays to contain handles you must be certain */
42 /* that the GrowableArray does not outlive the HandleMark that contains */
43 /* the handles. Since GrowableArrays are typically resource allocated */
44 /* the following is an example of INCORRECT CODE, */
45 /* */
46 /* ResourceMark rm; */
47 /* GrowableArray<Handle>* arr = new GrowableArray<Handle>(size); */
48 /* if (blah) { */
448 int new_len = this->_len + array_len;
449 if (new_len >= this->_capacity) grow(new_len);
450
451 for (int j = this->_len - 1; j >= idx; j--) {
452 this->_data[j + array_len] = this->_data[j];
453 }
454
455 for (int j = 0; j < array_len; j++) {
456 this->_data[idx + j] = array->at(j);
457 }
458
459 this->_len += array_len;
460 }
461
462 void appendAll(const GrowableArrayView<E>* l) {
463 for (int i = 0; i < l->length(); i++) {
464 this->at_put_grow(this->_len, l->at(i), E());
465 }
466 }
467
468 // Binary search and insertion utility. Search array for element
469 // matching key according to the static compare function. Insert
470 // that element if not already in the list. Assumes the list is
471 // already sorted according to compare function.
472 template <int compare(const E&, const E&)> E insert_sorted(const E& key) {
473 bool found;
474 int location = GrowableArrayView<E>::template find_sorted<E, compare>(key, found);
475 if (!found) {
476 insert_before(location, key);
477 }
478 return this->at(location);
479 }
480
481 E insert_sorted(CompareClosure<E>* cc, const E& key) {
482 bool found;
483 int location = find_sorted(cc, key, found);
484 if (!found) {
485 insert_before(location, key);
486 }
487 return this->at(location);
862 return _position == rhs._position;
863 }
864
865 bool operator!=(const GrowableArrayIterator<E>& rhs) {
866 assert(_array == rhs._array, "iterator belongs to different array");
867 return _position != rhs._position;
868 }
869 };
870
871 // Custom STL-style iterator to iterate over elements of a GrowableArray that satisfy a given predicate
872 template <typename E, class UnaryPredicate>
873 class GrowableArrayFilterIterator : public StackObj {
874 friend class GrowableArrayView<E>;
875
876 private:
877 const GrowableArrayView<E>* _array; // GrowableArray we iterate over
878 int _position; // Current position in the GrowableArray
879 UnaryPredicate _predicate; // Unary predicate the elements of the GrowableArray should satisfy
880
881 public:
882 GrowableArrayFilterIterator(const GrowableArrayIterator<E>& begin, UnaryPredicate filter_predicate) :
883 _array(begin._array), _position(begin._position), _predicate(filter_predicate) {
884 // Advance to first element satisfying the predicate
885 while(_position != _array->length() && !_predicate(_array->at(_position))) {
886 ++_position;
887 }
888 }
889
890 GrowableArrayFilterIterator<E, UnaryPredicate>& operator++() {
891 do {
892 // Advance to next element satisfying the predicate
893 ++_position;
894 } while(_position != _array->length() && !_predicate(_array->at(_position)));
895 return *this;
896 }
897
898 E operator*() { return _array->at(_position); }
899
900 bool operator==(const GrowableArrayIterator<E>& rhs) {
901 assert(_array == rhs._array, "iterator belongs to different array");
902 return _position == rhs._position;
903 }
904
905 bool operator!=(const GrowableArrayIterator<E>& rhs) {
906 assert(_array == rhs._array, "iterator belongs to different array");
907 return _position != rhs._position;
908 }
909
910 bool operator==(const GrowableArrayFilterIterator<E, UnaryPredicate>& rhs) {
911 assert(_array == rhs._array, "iterator belongs to different array");
912 return _position == rhs._position;
913 }
914
915 bool operator!=(const GrowableArrayFilterIterator<E, UnaryPredicate>& rhs) {
916 assert(_array == rhs._array, "iterator belongs to different array");
917 return _position != rhs._position;
918 }
919 };
920
921 // Arrays for basic types
922 typedef GrowableArray<int> intArray;
923 typedef GrowableArray<int> intStack;
924 typedef GrowableArray<bool> boolArray;
925
926 #endif // SHARE_UTILITIES_GROWABLEARRAY_HPP
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_UTILITIES_GROWABLEARRAY_HPP
26 #define SHARE_UTILITIES_GROWABLEARRAY_HPP
27
28 #include "memory/allocation.hpp"
29 #include "oops/array.hpp"
30 #include "oops/oop.hpp"
31 #include "memory/iterator.hpp"
32 #include "utilities/debug.hpp"
33 #include "utilities/globalDefinitions.hpp"
34 #include "utilities/ostream.hpp"
35 #include "utilities/powerOfTwo.hpp"
36
37 // A growable array.
38
39 /*************************************************************************/
40 /* */
41 /* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING */
42 /* */
43 /* Should you use GrowableArrays to contain handles you must be certain */
44 /* that the GrowableArray does not outlive the HandleMark that contains */
45 /* the handles. Since GrowableArrays are typically resource allocated */
46 /* the following is an example of INCORRECT CODE, */
47 /* */
48 /* ResourceMark rm; */
49 /* GrowableArray<Handle>* arr = new GrowableArray<Handle>(size); */
50 /* if (blah) { */
450 int new_len = this->_len + array_len;
451 if (new_len >= this->_capacity) grow(new_len);
452
453 for (int j = this->_len - 1; j >= idx; j--) {
454 this->_data[j + array_len] = this->_data[j];
455 }
456
457 for (int j = 0; j < array_len; j++) {
458 this->_data[idx + j] = array->at(j);
459 }
460
461 this->_len += array_len;
462 }
463
464 void appendAll(const GrowableArrayView<E>* l) {
465 for (int i = 0; i < l->length(); i++) {
466 this->at_put_grow(this->_len, l->at(i), E());
467 }
468 }
469
470 void appendAll(const Array<E>* l) {
471 for (int i = 0; i < l->length(); i++) {
472 this->at_put_grow(this->_len, l->at(i), E());
473 }
474 }
475
476 // Binary search and insertion utility. Search array for element
477 // matching key according to the static compare function. Insert
478 // that element if not already in the list. Assumes the list is
479 // already sorted according to compare function.
480 template <int compare(const E&, const E&)> E insert_sorted(const E& key) {
481 bool found;
482 int location = GrowableArrayView<E>::template find_sorted<E, compare>(key, found);
483 if (!found) {
484 insert_before(location, key);
485 }
486 return this->at(location);
487 }
488
489 E insert_sorted(CompareClosure<E>* cc, const E& key) {
490 bool found;
491 int location = find_sorted(cc, key, found);
492 if (!found) {
493 insert_before(location, key);
494 }
495 return this->at(location);
870 return _position == rhs._position;
871 }
872
873 bool operator!=(const GrowableArrayIterator<E>& rhs) {
874 assert(_array == rhs._array, "iterator belongs to different array");
875 return _position != rhs._position;
876 }
877 };
878
879 // Custom STL-style iterator to iterate over elements of a GrowableArray that satisfy a given predicate
880 template <typename E, class UnaryPredicate>
881 class GrowableArrayFilterIterator : public StackObj {
882 friend class GrowableArrayView<E>;
883
884 private:
885 const GrowableArrayView<E>* _array; // GrowableArray we iterate over
886 int _position; // Current position in the GrowableArray
887 UnaryPredicate _predicate; // Unary predicate the elements of the GrowableArray should satisfy
888
889 public:
890 GrowableArrayFilterIterator(const GrowableArray<E>* array, UnaryPredicate filter_predicate) :
891 _array(array), _position(0), _predicate(filter_predicate) {
892 // Advance to first element satisfying the predicate
893 while(!at_end() && !_predicate(_array->at(_position))) {
894 ++_position;
895 }
896 }
897
898 GrowableArrayFilterIterator<E, UnaryPredicate>& operator++() {
899 do {
900 // Advance to next element satisfying the predicate
901 ++_position;
902 } while(!at_end() && !_predicate(_array->at(_position)));
903 return *this;
904 }
905
906 E operator*() { return _array->at(_position); }
907
908 bool operator==(const GrowableArrayIterator<E>& rhs) {
909 assert(_array == rhs._array, "iterator belongs to different array");
910 return _position == rhs._position;
911 }
912
913 bool operator!=(const GrowableArrayIterator<E>& rhs) {
914 assert(_array == rhs._array, "iterator belongs to different array");
915 return _position != rhs._position;
916 }
917
918 bool operator==(const GrowableArrayFilterIterator<E, UnaryPredicate>& rhs) {
919 assert(_array == rhs._array, "iterator belongs to different array");
920 return _position == rhs._position;
921 }
922
923 bool operator!=(const GrowableArrayFilterIterator<E, UnaryPredicate>& rhs) {
924 assert(_array == rhs._array, "iterator belongs to different array");
925 return _position != rhs._position;
926 }
927
928 bool at_end() const {
929 return _array == nullptr || _position == _array->end()._position;
930 }
931 };
932
933 // Arrays for basic types
934 typedef GrowableArray<int> intArray;
935 typedef GrowableArray<int> intStack;
936 typedef GrowableArray<bool> boolArray;
937
938 #endif // SHARE_UTILITIES_GROWABLEARRAY_HPP
|