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)
62 void SimpleMemberFunction(int num, const char *str)
64 LogDebug("In SimpleMemberFunction in " << m_name << ". Num="
65 << num << ", str = " << str);
68 int SimpleMemberFunctionReturnsInt(int num, const char *str)
70 LogDebug("In SimpleMemberFunctionReturnsInt in " << m_name << ". Num="
71 << num << ", str = " << str);
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()
103 virtual void UnusedVirtualFunction(void)
106 virtual void TrickyVirtualFunction(int num, const char *str) = 0;
111 int letsMakeThingsComplicated[400];
114 // This declaration ensures that we get a convoluted class heirarchy.
116 : public VeryBigClass,
117 virtual public COtherClass,
118 virtual public CBaseClass
120 double m_somemember[8];
124 : CBaseClass("Base of Derived")
126 m_somemember[0] = 1.2345;
129 void SimpleDerivedFunction(int num, const char *str)
131 LogDebug("In SimpleDerivedFunction Num="
132 << num << ", str = " << str);
135 virtual void AnotherUnusedVirtualFunction(int num, const char *str)
137 LogDebug("In AnotherUnusedVirtualFunction in " << m_name << ". Num="
138 << num << ", str = " << 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;
167 MyDelegate funclist[12]; // delegates are initialized to empty
168 CBaseClass a("Base A");
169 CBaseClass b("Base B");
173 IntMyDelegate newdeleg;
174 newdeleg = DPL::MakeDelegate(&a,
175 &CBaseClass::SimpleMemberFunctionReturnsInt);
177 // Binding a simple member function
178 funclist[0].bind(&a, &CBaseClass::SimpleMemberFunction);
180 // You can also bind static (free) functions
181 funclist[1].bind(&SimpleStaticFunction);
183 // and static member functions
184 funclist[2].bind(&CBaseClass::StaticMemberFunction);
186 // and const member functions (these only need a const class pointer).
187 funclist[3].bind((const CBaseClass *) &a,
188 &CBaseClass::ConstMemberFunction);
190 funclist[4].bind(&a, &CBaseClass::ConstMemberFunction);
192 // and virtual member functions
193 funclist[5].bind(&b, &CBaseClass::SimpleVirtualFunction);
195 // You can also use the = operator. For static functions, a fastdelegate
196 // looks identical to a simple function pointer.
197 funclist[6] = &CBaseClass::StaticMemberFunction;
199 // The weird rule about the class of derived member function pointers
200 // is avoided. For MSVC, you can use &CDerivedClass::SimpleVirtualFunction
201 // here, but DMC will complain. Note that as well as .bind(), you can also
202 // use the MakeDelegate() global function.
203 funclist[7] = DPL::MakeDelegate(&d, &CBaseClass::SimpleVirtualFunction);
205 // The worst case is an abstract virtual function of a virtually-derived
206 // class with at least one non-virtual base class. This is a VERY obscure
207 // situation, which you're unlikely to encounter in the real world.
208 // FastDelegate versions prior to 1.3 had problems with this case on VC6.
209 // Now, it works without problems on all compilers.
210 funclist[8].bind(&c, &CDerivedClass::TrickyVirtualFunction);
212 // BUT... in such cases you should be using the base class as an
213 // interface, anyway.
214 funclist[9].bind(&c, &COtherClass::TrickyVirtualFunction);
216 // Calling a function that was first declared in the derived class is
218 funclist[10] = DPL::MakeDelegate(&c, &CDerivedClass::SimpleDerivedFunction);
220 // You can also bind directly using the constructor
221 MyDelegate dg(&b, &CBaseClass::SimpleVirtualFunction);
223 const char *msg = "Looking for equal delegate";
225 for (int i = 0; i < 12; i++)
229 // The == and != operators are provided
230 // Note that they work even for inline functions.
231 if (funclist[i] == dg)
233 msg = "Found equal delegate";
236 // operator ! can be used to test for an empty delegate
237 // You can also use the .empty() member function.
240 LogDebug("Delegate is empty");
244 // Invocation generates optimal assembly code.