2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * @file test_fast_delegate.cpp
18 * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
20 * @brief This file is the implementation file of fast delegate tests.
22 #include <dpl/test/test_runner.h>
23 #include <dpl/fast_delegate.h>
24 #include <dpl/log/log.h>
26 RUNNER_TEST_GROUP_INIT(DPL)
28 // Sample copied and adopted from
29 // http://www.codeproject.com/KB/cpp/FastDelegate.aspx
31 // Demonstrate the syntax for FastDelegates.
32 // -Don Clugston, May 2004.
33 // It's a really boring example, but it shows the most important cases.
34 // Declare some functions of varying complexity...
35 void SimpleStaticFunction(int num, const char *str);
36 void SimpleStaticFunction(int num, const char *str)
38 LogDebug("In SimpleStaticFunction. Num=" << num << ", str =" << str);
41 void SimpleVoidFunction();
42 void SimpleVoidFunction()
44 LogDebug("In SimpleVoidFunction with no parameters.");
53 CBaseClass(const char *name) :
60 void SimpleMemberFunction(int num, const char *str)
62 LogDebug("In SimpleMemberFunction in " << m_name << ". Num="
63 << num << ", str = " << str);
66 int SimpleMemberFunctionReturnsInt(int num, const char *str)
69 "In SimpleMemberFunctionReturnsInt in " << m_name << ". Num="
75 void ConstMemberFunction(int num, const char *str) const
77 LogDebug("In ConstMemberFunction in " << m_name << ". Num="
78 << num << ", str = " << str);
81 virtual void SimpleVirtualFunction(int num, const char *str)
83 LogDebug("In SimpleVirtualFunction in " << m_name << ". Num="
84 << num << ", str = " << str);
87 static void StaticMemberFunction(int num, const char *str)
89 LogDebug("In StaticMemberFunction Num="
90 << num << ", str = " << str);
96 double rubbish; // to ensure this class has non-zero size.
99 virtual ~COtherClass()
102 virtual void UnusedVirtualFunction(void)
104 virtual void TrickyVirtualFunction(int num, const char *str) = 0;
109 int letsMakeThingsComplicated[400];
112 // This declaration ensures that we get a convoluted class heirarchy.
113 class CDerivedClass :
115 virtual public COtherClass,
116 virtual public CBaseClass
118 double m_somemember[8];
122 CBaseClass("Base of Derived")
124 m_somemember[0] = 1.2345;
127 void SimpleDerivedFunction(int num, const char *str)
129 LogDebug("In SimpleDerivedFunction Num="
130 << num << ", str = " << str);
133 virtual void AnotherUnusedVirtualFunction(int num, const char *str)
136 "In AnotherUnusedVirtualFunction in " << m_name << ". Num="
137 << num << ", str = " <<
141 virtual void TrickyVirtualFunction(int num, const char *str)
143 LogDebug("In TrickyVirtualFunction in " << m_name << ". Num="
144 << num << ", str = " << str);
148 RUNNER_TEST(FastDelegate_Test)
150 // Delegates with up to 8 parameters are supported.
151 // Here's the case for a void function.
152 // We declare a delegate and attach it to SimpleVoidFunction()
153 DPL::FastDelegate0<> noparameterdelegate(&SimpleVoidFunction);
155 // invoke the delegate - this calls SimpleVoidFunction()
156 noparameterdelegate();
158 LogDebug("-- Examples using two-parameter delegates (int, char *) --");
160 // By default, the return value is void.
161 typedef DPL::FastDelegate2<int, const char *> MyDelegate;
163 // If you want to have a non-void return value, put it at the end.
164 typedef DPL::FastDelegate2<int, const char *, int> IntMyDelegate;
166 MyDelegate funclist[12]; // delegates are initialized to empty
167 CBaseClass a("Base A");
168 CBaseClass b("Base B");
172 IntMyDelegate newdeleg;
173 newdeleg = DPL::MakeDelegate(&a,
174 &CBaseClass::SimpleMemberFunctionReturnsInt);
176 // Binding a simple member function
177 funclist[0].bind(&a, &CBaseClass::SimpleMemberFunction);
179 // You can also bind static (free) functions
180 funclist[1].bind(&SimpleStaticFunction);
182 // and static member functions
183 funclist[2].bind(&CBaseClass::StaticMemberFunction);
185 // and const member functions (these only need a const class pointer).
186 funclist[3].bind((const CBaseClass *) &a,
187 &CBaseClass::ConstMemberFunction);
189 funclist[4].bind(&a, &CBaseClass::ConstMemberFunction);
191 // and virtual member functions
192 funclist[5].bind(&b, &CBaseClass::SimpleVirtualFunction);
194 // You can also use the = operator. For static functions, a fastdelegate
195 // looks identical to a simple function pointer.
196 funclist[6] = &CBaseClass::StaticMemberFunction;
198 // The weird rule about the class of derived member function pointers
199 // is avoided. For MSVC, you can use &CDerivedClass::SimpleVirtualFunction
200 // here, but DMC will complain. Note that as well as .bind(), you can also
201 // use the MakeDelegate() global function.
202 funclist[7] = DPL::MakeDelegate(&d, &CBaseClass::SimpleVirtualFunction);
204 // The worst case is an abstract virtual function of a virtually-derived
205 // class with at least one non-virtual base class. This is a VERY obscure
206 // situation, which you're unlikely to encounter in the real world.
207 // FastDelegate versions prior to 1.3 had problems with this case on VC6.
208 // Now, it works without problems on all compilers.
209 funclist[8].bind(&c, &CDerivedClass::TrickyVirtualFunction);
211 // BUT... in such cases you should be using the base class as an
212 // interface, anyway.
213 funclist[9].bind(&c, &COtherClass::TrickyVirtualFunction);
215 // Calling a function that was first declared in the derived class is
217 funclist[10] = DPL::MakeDelegate(&c, &CDerivedClass::SimpleDerivedFunction);
219 // You can also bind directly using the constructor
220 MyDelegate dg(&b, &CBaseClass::SimpleVirtualFunction);
222 const char *msg = "Looking for equal delegate";
224 for (int i = 0; i < 12; i++) {
227 // The == and != operators are provided
228 // Note that they work even for inline functions.
229 if (funclist[i] == dg) {
230 msg = "Found equal delegate";
233 // operator ! can be used to test for an empty delegate
234 // You can also use the .empty() member function.
236 LogDebug("Delegate is empty");
238 // Invocation generates optimal assembly code.