references.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Boost.TypeErasure library
  2. //
  3. // Copyright 2011 Steven Watanabe
  4. //
  5. // Distributed under the Boost Software License Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // $Id$
  10. #include <boost/type_erasure/any.hpp>
  11. #include <boost/type_erasure/any_cast.hpp>
  12. #include <boost/type_erasure/builtin.hpp>
  13. #include <boost/type_erasure/operators.hpp>
  14. #include <boost/mpl/vector.hpp>
  15. #include <boost/shared_ptr.hpp>
  16. #include <iostream>
  17. namespace mpl = boost::mpl;
  18. using namespace boost::type_erasure;
  19. void references1() {
  20. //[references1
  21. /*`
  22. To capture by reference, we simply add a reference
  23. to the __placeholder.
  24. */
  25. int i;
  26. any<typeid_<>, _self&> x(i);
  27. any_cast<int&>(x) = 5; // now i is 5
  28. /*`
  29. [note `_self` is the default __placeholder, so it is
  30. easiest to use `_self&`. We could use another
  31. __placeholder instead. __any`<`__typeid_`<_a>, _a&>` has
  32. exactly the same behavior.]
  33. */
  34. //]
  35. }
  36. void references2() {
  37. //[references2
  38. /*`
  39. References cannot be rebound. Just like a built-in C++ reference,
  40. once you've initialized it you can't change it to point to
  41. something else.
  42. ``
  43. int i, j;
  44. any<typeid_<>, _self&> x(i), y(j);
  45. x = y; // error
  46. ``
  47. [note As with any other operation, `x = y` for references
  48. acts on `i` and `j`. Assignment like this is legal
  49. if __assignable`<>` is in the Concept, but `x` would
  50. still hold a reference to `i`.]
  51. */
  52. //]
  53. }
  54. void references3() {
  55. //[references3
  56. /*`
  57. A reference can be bound to another __any.
  58. */
  59. typedef mpl::vector<
  60. copy_constructible<>,
  61. incrementable<>
  62. > requirements;
  63. any<requirements> x(10);
  64. any<requirements, _self&> y(x);
  65. ++y; // x is now 11
  66. //]
  67. }
  68. void references4() {
  69. //[references4
  70. /*`
  71. If a reference is used after the underlying object
  72. goes out of scope or is reset, the behavior is undefined.
  73. */
  74. typedef mpl::vector<
  75. copy_constructible<>,
  76. incrementable<>,
  77. relaxed
  78. > requirements;
  79. any<requirements> x(10);
  80. any<requirements, _self&> y(x);
  81. x = 1.0;
  82. ++y; // undefined behavior.
  83. //]
  84. }
  85. void references5() {
  86. typedef mpl::vector<
  87. copy_constructible<>,
  88. incrementable<>
  89. > requirements;
  90. //[references5
  91. /*`
  92. This only applies when a reference is constructed
  93. from a value. If a reference is constructed from another
  94. reference, the new reference does not depend on the old one.
  95. */
  96. any<requirements> x(10);
  97. boost::shared_ptr<any<requirements, _self&> > p(
  98. new any<requirements, _self&>(x));
  99. any<requirements, _self&> y(*p); // equivalent to y(x);
  100. p.reset();
  101. ++y; // okay
  102. //]
  103. }
  104. void references6() {
  105. //[references6
  106. /*`
  107. Both const and non-const references are supported.
  108. */
  109. int i = 0;
  110. any<incrementable<>, _self&> x(i);
  111. any<incrementable<>, const _self&> y(x);
  112. /*`
  113. A reference to non-const can be converted to a reference
  114. to const, but not the other way around. Naturally,
  115. we can't apply mutating operations to a const reference.
  116. any<incrementable<>, _self&> z(y); // error
  117. ++y; // error
  118. */
  119. //]
  120. }
  121. //[references
  122. //` (For the source of the examples in this section see
  123. //` [@boost:/libs/type_erasure/example/references.cpp references.cpp])
  124. //` [references1]
  125. //` [references2]
  126. //` [references3]
  127. //` [references4]
  128. //` [references5]
  129. //` [references6]
  130. //]