Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : */
9 :
10 : namespace detail
11 : {
12 :
13 : template<typename T>
14 : struct has_clone
15 : {
16 : template<typename U, U x>
17 : struct test;
18 :
19 : typedef char yes;
20 : typedef struct { char a[2]; } no;
21 :
22 : template<typename U>
23 : static yes& check_sig(U*, test<U* (U::*)() const, &U::clone>* = 0);
24 : template<typename U>
25 : static no& check_sig(...);
26 :
27 : enum
28 : {
29 : value = sizeof(check_sig<T>(0)) == sizeof(yes)
30 : };
31 : };
32 :
33 : template<typename T, bool HasClone>
34 : struct cloner
35 : {
36 0 : static T* clone(T* const other)
37 : {
38 0 : return new T(*other);
39 : }
40 : };
41 :
42 : template<typename T>
43 : struct cloner<T, true>
44 : {
45 0 : static T* clone(T* const other)
46 : {
47 0 : return other->clone();
48 : }
49 : };
50 :
51 : }
52 :
53 : /** Creates a new copy of the passed object.
54 : If other is 0, just returns 0. Otherwise, if other has function
55 : named clone with signature T* (T::*)() const, the function is called.
56 : Otherwise, copy constructor is used.
57 :
58 : @returns 0 or newly allocated object
59 : */
60 : template<typename T>
61 0 : T* clone(T* const other)
62 : {
63 0 : return other ? ::detail::cloner<T, ::detail::has_clone<T>::value>::clone(other) : 0;
64 : }
65 :
66 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|