IntrusiveList.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*
  2. * Copyright 2011-present Facebook, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #pragma once
  17. /*
  18. * This file contains convenience aliases that make boost::intrusive::list
  19. * easier to use.
  20. */
  21. #include <boost/intrusive/list.hpp>
  22. namespace folly {
  23. /**
  24. * An auto-unlink intrusive list hook.
  25. */
  26. using IntrusiveListHook = boost::intrusive::list_member_hook<
  27. boost::intrusive::link_mode<boost::intrusive::auto_unlink>>;
  28. /**
  29. * An intrusive list.
  30. *
  31. * An IntrusiveList always uses an auto-unlink hook.
  32. * Beware that IntrusiveList::size() is an O(n) operation, since it has to walk
  33. * the entire list.
  34. *
  35. * Example usage:
  36. *
  37. * class Foo {
  38. * // Note that the listHook member variable needs to be visible
  39. * // to the code that defines the IntrusiveList instantiation.
  40. * // The list hook can be made public, or you can make the other class a
  41. * // friend.
  42. * IntrusiveListHook listHook;
  43. * };
  44. *
  45. * using FooList = IntrusiveList<Foo, &Foo::listHook>;
  46. *
  47. * Foo *foo = new Foo();
  48. * FooList myList;
  49. * myList.push_back(*foo);
  50. *
  51. * Note that each IntrusiveListHook can only be part of a single list at any
  52. * given time. If you need the same object to be stored in two lists at once,
  53. * you need to use two different IntrusiveListHook member variables.
  54. *
  55. * The elements stored in the list must contain an IntrusiveListHook member
  56. * variable.
  57. */
  58. template <typename T, IntrusiveListHook T::*PtrToMember>
  59. using IntrusiveList = boost::intrusive::list<
  60. T,
  61. boost::intrusive::member_hook<T, IntrusiveListHook, PtrToMember>,
  62. boost::intrusive::constant_time_size<false>>;
  63. /**
  64. * A safe-link intrusive list hook.
  65. */
  66. using SafeIntrusiveListHook = boost::intrusive::list_member_hook<
  67. boost::intrusive::link_mode<boost::intrusive::safe_link>>;
  68. /**
  69. * An intrusive list with const-time size() method.
  70. *
  71. * A CountedIntrusiveList always uses a safe-link hook.
  72. * CountedIntrusiveList::size() is an O(1) operation. Users of this type
  73. * of lists need to remove a member from a list by calling one of the
  74. * methods on the list (e.g., erase(), pop_front(), etc.), rather than
  75. * calling unlink on the member's list hook. Given references to a
  76. * list and a member, a constant-time removal operation can be
  77. * accomplished by list.erase(list.iterator_to(member)). Also, when a
  78. * member is destroyed, it is NOT automatically removed from the list.
  79. *
  80. * Example usage:
  81. *
  82. * class Foo {
  83. * // Note that the listHook member variable needs to be visible
  84. * // to the code that defines the CountedIntrusiveList instantiation.
  85. * // The list hook can be made public, or you can make the other class a
  86. * // friend.
  87. * SafeIntrusiveListHook listHook;
  88. * };
  89. *
  90. * using FooList = CountedIntrusiveList<Foo, &Foo::listHook> FooList;
  91. *
  92. * Foo *foo = new Foo();
  93. * FooList myList;
  94. * myList.push_back(*foo);
  95. * myList.pop_front();
  96. *
  97. * Note that each SafeIntrusiveListHook can only be part of a single list at any
  98. * given time. If you need the same object to be stored in two lists at once,
  99. * you need to use two different SafeIntrusiveListHook member variables.
  100. *
  101. * The elements stored in the list must contain an SafeIntrusiveListHook member
  102. * variable.
  103. */
  104. template <typename T, SafeIntrusiveListHook T::*PtrToMember>
  105. using CountedIntrusiveList = boost::intrusive::list<
  106. T,
  107. boost::intrusive::member_hook<T, SafeIntrusiveListHook, PtrToMember>,
  108. boost::intrusive::constant_time_size<true>>;
  109. } // namespace folly