doubleptr.h 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. // Copyright 2012 Google Inc. All Rights Reserved.
  2. // Author: rays@google.com (Ray Smith)
  3. ///////////////////////////////////////////////////////////////////////
  4. // File: doubleptr.h
  5. // Description: Double-ended pointer that keeps pointing correctly even
  6. // when reallocated or copied.
  7. // Author: Ray Smith
  8. //
  9. // (C) Copyright 2012, Google Inc.
  10. // Licensed under the Apache License, Version 2.0 (the "License");
  11. // you may not use this file except in compliance with the License.
  12. // You may obtain a copy of the License at
  13. // http://www.apache.org/licenses/LICENSE-2.0
  14. // Unless required by applicable law or agreed to in writing, software
  15. // distributed under the License is distributed on an "AS IS" BASIS,
  16. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17. // See the License for the specific language governing permissions and
  18. // limitations under the License.
  19. //
  20. ///////////////////////////////////////////////////////////////////////
  21. #ifndef TESSERACT_CCUTIL_DOUBLEPTR_H_
  22. #define TESSERACT_CCUTIL_DOUBLEPTR_H_
  23. #include "errcode.h"
  24. namespace tesseract {
  25. // A smart pointer class that implements a double-ended pointer. Each end
  26. // points to the other end. The copy constructor and operator= have MOVE
  27. // semantics, meaning that the relationship with the other end moves to the
  28. // destination of the copy, leaving the source unattached.
  29. // For this reason both the copy constructor and the operator= take a non-const
  30. // reference argument, and the const reference versions cannot be used.
  31. // DoublePtr is useful to incorporate into structures that are part of a
  32. // collection such as STL containers, where reallocs can
  33. // relocate the members. DoublePtr is also useful in a GenericHeap, where it
  34. // can correctly maintain the pointer to an element of the heap despite it
  35. // getting moved around on the heap.
  36. class DoublePtr {
  37. public:
  38. DoublePtr() : other_end_(nullptr) {}
  39. // Copy constructor steals the partner off src and is therefore a non
  40. // const reference arg.
  41. // Copying a const DoublePtr generates a compiler error.
  42. DoublePtr(const DoublePtr &src) {
  43. other_end_ = src.other_end_;
  44. if (other_end_ != nullptr) {
  45. other_end_->other_end_ = this;
  46. ((DoublePtr &)src).other_end_ = nullptr;
  47. }
  48. }
  49. // Operator= steals the partner off src, and therefore needs src to be a non-
  50. // const reference.
  51. // Assigning from a const DoublePtr generates a compiler error.
  52. void operator=(const DoublePtr &src) {
  53. Disconnect();
  54. other_end_ = src.other_end_;
  55. if (other_end_ != nullptr) {
  56. other_end_->other_end_ = this;
  57. ((DoublePtr &)src).other_end_ = nullptr;
  58. }
  59. }
  60. // Connects this and other, discarding any existing connections.
  61. void Connect(DoublePtr *other) {
  62. other->Disconnect();
  63. Disconnect();
  64. other->other_end_ = this;
  65. other_end_ = other;
  66. }
  67. // Disconnects this and other, making OtherEnd() return nullptr for both.
  68. void Disconnect() {
  69. if (other_end_ != nullptr) {
  70. other_end_->other_end_ = nullptr;
  71. other_end_ = nullptr;
  72. }
  73. }
  74. // Returns the pointer to the other end of the double pointer.
  75. DoublePtr *OtherEnd() const {
  76. return other_end_;
  77. }
  78. private:
  79. // Pointer to the other end of the link. It is always true that either
  80. // other_end_ == nullptr or other_end_->other_end_ == this.
  81. DoublePtr *other_end_;
  82. };
  83. } // namespace tesseract.
  84. #endif // THIRD_PARTY_TESSERACT_CCUTIL_DOUBLEPTR_H_