Functional.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /*
  2. * Copyright (C) 2011 Apple Inc. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
  14. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  15. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
  17. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  18. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  19. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  20. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  21. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  22. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  23. * THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #include "config.h"
  26. #include <wtf/RefCounted.h>
  27. #include <wtf/Functional.h>
  28. namespace TestWebKitAPI {
  29. static int returnFortyTwo()
  30. {
  31. return 42;
  32. }
  33. TEST(FunctionalTest, Basic)
  34. {
  35. Function<int ()> emptyFunction;
  36. ASSERT_TRUE(emptyFunction.isNull());
  37. Function<int ()> returnFortyTwoFunction = bind(returnFortyTwo);
  38. ASSERT_FALSE(returnFortyTwoFunction.isNull());
  39. ASSERT_EQ(42, returnFortyTwoFunction());
  40. }
  41. static int multiplyByTwo(int n)
  42. {
  43. return n * 2;
  44. }
  45. static double multiplyByOneAndAHalf(double d)
  46. {
  47. return d * 1.5;
  48. }
  49. TEST(FunctionalTest, UnaryBind)
  50. {
  51. Function<int ()> multiplyFourByTwoFunction = bind(multiplyByTwo, 4);
  52. ASSERT_EQ(8, multiplyFourByTwoFunction());
  53. Function<double ()> multiplyByOneAndAHalfFunction = bind(multiplyByOneAndAHalf, 3);
  54. ASSERT_EQ(4.5, multiplyByOneAndAHalfFunction());
  55. }
  56. static int multiply(int x, int y)
  57. {
  58. return x * y;
  59. }
  60. static int subtract(int x, int y)
  61. {
  62. return x - y;
  63. }
  64. TEST(FunctionalTest, BinaryBind)
  65. {
  66. Function<int ()> multiplyFourByTwoFunction = bind(multiply, 4, 2);
  67. ASSERT_EQ(8, multiplyFourByTwoFunction());
  68. Function<int ()> subtractTwoFromFourFunction = bind(subtract, 4, 2);
  69. ASSERT_EQ(2, subtractTwoFromFourFunction());
  70. }
  71. class A {
  72. public:
  73. explicit A(int i)
  74. : m_i(i)
  75. {
  76. }
  77. int f() { return m_i; }
  78. int addF(int j) { return m_i + j; }
  79. private:
  80. int m_i;
  81. };
  82. TEST(FunctionalTest, MemberFunctionBind)
  83. {
  84. A a(10);
  85. Function<int ()> function1 = bind(&A::f, &a);
  86. ASSERT_EQ(10, function1());
  87. Function<int ()> function2 = bind(&A::addF, &a, 15);
  88. ASSERT_EQ(25, function2());
  89. }
  90. class B {
  91. public:
  92. B()
  93. : m_numRefCalls(0)
  94. , m_numDerefCalls(0)
  95. {
  96. }
  97. ~B()
  98. {
  99. }
  100. void ref()
  101. {
  102. m_numRefCalls++;
  103. }
  104. void deref()
  105. {
  106. m_numDerefCalls++;
  107. }
  108. void f() { ASSERT_GT(m_numRefCalls, 0); }
  109. void g(int) { ASSERT_GT(m_numRefCalls, 0); }
  110. int m_numRefCalls;
  111. int m_numDerefCalls;
  112. };
  113. TEST(FunctionalTest, MemberFunctionBindRefDeref)
  114. {
  115. B b;
  116. {
  117. Function<void ()> function1 = bind(&B::f, &b);
  118. function1();
  119. Function<void ()> function2 = bind(&B::g, &b, 10);
  120. function2();
  121. }
  122. ASSERT_TRUE(b.m_numRefCalls == b.m_numDerefCalls);
  123. ASSERT_GT(b.m_numRefCalls, 0);
  124. }
  125. class Number : public RefCounted<Number> {
  126. public:
  127. static PassRefPtr<Number> create(int value)
  128. {
  129. return adoptRef(new Number(value));
  130. }
  131. ~Number()
  132. {
  133. m_value = 0;
  134. }
  135. int value() const { return m_value; }
  136. private:
  137. explicit Number(int value)
  138. : m_value(value)
  139. {
  140. }
  141. int m_value;
  142. };
  143. static int multiplyNumberByTwo(Number* number)
  144. {
  145. return number->value() * 2;
  146. }
  147. TEST(FunctionalTest, RefCountedStorage)
  148. {
  149. RefPtr<Number> five = Number::create(5);
  150. Function<int ()> multiplyFiveByTwoFunction = bind(multiplyNumberByTwo, five);
  151. ASSERT_EQ(10, multiplyFiveByTwoFunction());
  152. Function<int ()> multiplyFourByTwoFunction = bind(multiplyNumberByTwo, Number::create(4));
  153. ASSERT_EQ(8, multiplyFourByTwoFunction());
  154. RefPtr<Number> six = Number::create(6);
  155. Function<int ()> multiplySixByTwoFunction = bind(multiplyNumberByTwo, six.release());
  156. ASSERT_FALSE(six);
  157. ASSERT_EQ(12, multiplySixByTwoFunction());
  158. }
  159. namespace RefAndDerefTests {
  160. template<typename T> struct RefCounted {
  161. void ref();
  162. void deref();
  163. };
  164. struct Connection : RefCounted<Connection> { };
  165. COMPILE_ASSERT(WTF::HasRefAndDeref<Connection>::value, class_has_ref_and_deref);
  166. struct NoRefOrDeref { };
  167. COMPILE_ASSERT(!WTF::HasRefAndDeref<NoRefOrDeref>::value, class_has_no_ref_or_deref);
  168. struct RefOnly { void ref(); };
  169. COMPILE_ASSERT(!WTF::HasRefAndDeref<RefOnly>::value, class_has_ref_only);
  170. struct DerefOnly { void deref(); };
  171. COMPILE_ASSERT(!WTF::HasRefAndDeref<DerefOnly>::value, class_has_deref_only);
  172. }
  173. } // namespace TestWebKitAPI