OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_ | 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_ |
6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_ | 6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_ |
7 | 7 |
8 #include <new> | 8 #include <new> |
9 #include <type_traits> | 9 #include <type_traits> |
10 #include <vector> | 10 #include <vector> |
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
486 static_assert(sizeof(Array_Data<char>) == 8, "Bad sizeof(Array_Data)"); | 486 static_assert(sizeof(Array_Data<char>) == 8, "Bad sizeof(Array_Data)"); |
487 | 487 |
488 // UTF-8 encoded | 488 // UTF-8 encoded |
489 typedef Array_Data<char> String_Data; | 489 typedef Array_Data<char> String_Data; |
490 | 490 |
491 template <typename T, bool kIsMoveOnlyType> | 491 template <typename T, bool kIsMoveOnlyType> |
492 struct ArrayTraits {}; | 492 struct ArrayTraits {}; |
493 | 493 |
494 template <typename T> | 494 template <typename T> |
495 struct ArrayTraits<T, false> { | 495 struct ArrayTraits<T, false> { |
496 typedef T StorageType; | 496 typedef typename std::vector<T>::const_reference ForwardType; |
497 typedef typename std::vector<T>::reference RefType; | |
498 typedef typename std::vector<T>::const_reference ConstRefType; | |
499 typedef ConstRefType ForwardType; | |
500 static inline void Finalize(std::vector<T>* vec) {} | |
501 static inline ConstRefType at(const std::vector<T>* vec, size_t offset) { | |
502 return vec->at(offset); | |
503 } | |
504 static inline RefType at(std::vector<T>* vec, size_t offset) { | |
505 return vec->at(offset); | |
506 } | |
507 static inline void Resize(std::vector<T>* vec, size_t size) { | |
508 vec->resize(size); | |
509 } | |
510 static inline void PushBack(std::vector<T>* vec, ForwardType value) { | 497 static inline void PushBack(std::vector<T>* vec, ForwardType value) { |
511 vec->push_back(value); | 498 vec->push_back(value); |
512 } | 499 } |
513 static inline void Clone(const std::vector<T>& src_vec, | 500 static inline void Clone(const std::vector<T>& src_vec, |
514 std::vector<T>* dest_vec) { | 501 std::vector<T>* dest_vec) { |
515 dest_vec->assign(src_vec.begin(), src_vec.end()); | 502 dest_vec->assign(src_vec.begin(), src_vec.end()); |
516 } | 503 } |
517 }; | 504 }; |
518 | 505 |
519 template <typename T> | 506 template <typename T> |
520 struct ArrayTraits<T, true> { | 507 struct ArrayTraits<T, true> { |
521 struct StorageType { | |
522 char buf[sizeof(T) + (8 - (sizeof(T) % 8)) % 8]; // Make 8-byte aligned. | |
523 }; | |
524 typedef T& RefType; | |
525 typedef const T& ConstRefType; | |
526 typedef T ForwardType; | 508 typedef T ForwardType; |
527 static inline void Finalize(std::vector<StorageType>* vec) { | 509 static inline void PushBack(std::vector<T>* vec, T& value) { |
528 for (size_t i = 0; i < vec->size(); ++i) | 510 vec->push_back(value.Pass()); |
529 reinterpret_cast<T*>(vec->at(i).buf)->~T(); | |
530 } | 511 } |
531 static inline ConstRefType at(const std::vector<StorageType>* vec, | 512 static inline void Clone(const std::vector<T>& src_vec, |
532 size_t offset) { | 513 std::vector<T>* dest_vec) { |
533 return *reinterpret_cast<const T*>(vec->at(offset).buf); | 514 dest_vec->resize(src_vec.size()); |
534 } | |
535 static inline RefType at(std::vector<StorageType>* vec, size_t offset) { | |
536 return *reinterpret_cast<T*>(vec->at(offset).buf); | |
537 } | |
538 static inline void Resize(std::vector<StorageType>* vec, size_t size) { | |
539 size_t old_size = vec->size(); | |
540 for (size_t i = size; i < old_size; i++) | |
541 reinterpret_cast<T*>(vec->at(i).buf)->~T(); | |
542 ResizeStorage(vec, size); | |
543 for (size_t i = old_size; i < vec->size(); i++) | |
544 new (vec->at(i).buf) T(); | |
545 } | |
546 static inline void PushBack(std::vector<StorageType>* vec, RefType value) { | |
547 size_t old_size = vec->size(); | |
548 ResizeStorage(vec, old_size + 1); | |
549 new (vec->at(old_size).buf) T(value.Pass()); | |
550 } | |
551 static inline void ResizeStorage(std::vector<StorageType>* vec, size_t size) { | |
552 if (size <= vec->capacity()) { | |
553 vec->resize(size); | |
554 return; | |
555 } | |
556 std::vector<StorageType> new_storage(size); | |
557 for (size_t i = 0; i < vec->size(); i++) | |
558 new (new_storage.at(i).buf) T(at(vec, i).Pass()); | |
559 vec->swap(new_storage); | |
560 Finalize(&new_storage); | |
561 } | |
562 static inline void Clone(const std::vector<StorageType>& src_vec, | |
563 std::vector<StorageType>* dest_vec) { | |
564 Resize(dest_vec, src_vec.size()); | |
565 for (size_t i = 0; i < src_vec.size(); ++i) | 515 for (size_t i = 0; i < src_vec.size(); ++i) |
566 at(dest_vec, i) = at(&src_vec, i).Clone(); | 516 dest_vec->at(i) = src_vec.at(i).Clone(); |
567 } | 517 } |
568 }; | 518 }; |
569 | 519 |
570 template <> | 520 template <> |
571 struct WrapperTraits<String, false> { | 521 struct WrapperTraits<String, false> { |
572 typedef String_Data* DataType; | 522 typedef String_Data* DataType; |
573 }; | 523 }; |
574 | 524 |
575 } // namespace internal | 525 } // namespace internal |
576 } // namespace mojo | 526 } // namespace mojo |
577 | 527 |
578 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_ | 528 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_ |
OLD | NEW |