1 /************************************************************************
2  **
3  **  @file   qoverload.h
4  **  @author Roman Telezhynskyi <dismine(at)gmail.com>
5  **  @date   12 1, 2018
6  **
7  **  @brief
8  **  @copyright
9  **  This source code is part of the Valentina project, a pattern making
10  **  program, whose allow create and modeling patterns of clothing.
11  **  Copyright (C) 2018 Valentina project
12  **  <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
13  **
14  **  Valentina is free software: you can redistribute it and/or modify
15  **  it under the terms of the GNU General Public License as published by
16  **  the Free Software Foundation, either version 3 of the License, or
17  **  (at your option) any later version.
18  **
19  **  Valentina is distributed in the hope that it will be useful,
20  **  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  **  GNU General Public License for more details.
23  **
24  **  You should have received a copy of the GNU General Public License
25  **  along with Valentina.  If not, see <http://www.gnu.org/licenses/>.
26  **
27  *************************************************************************/
28 #ifndef QOVERLOAD_H
29 #define QOVERLOAD_H
30 
31 #include <QtGlobal>
32 
33 #if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
34 #if defined(Q_COMPILER_VARIADIC_TEMPLATES)
35 
36 #include "../diagnostic.h"
37 
38 QT_WARNING_PUSH
39 QT_WARNING_DISABLE_GCC("-Weffc++")
40 
41 template <typename... Args>
42 struct QNonConstOverload
43 {
44     template <typename R, typename T>
45     Q_DECL_CONSTEXPR auto operator()(R (T::*ptr)(Args...)) const Q_DECL_NOTHROW -> decltype(ptr)
46     { return ptr; }
47 
48     template <typename R, typename T>
49     static Q_DECL_CONSTEXPR auto of(R (T::*ptr)(Args...)) Q_DECL_NOTHROW -> decltype(ptr)
50     { return ptr; }
51 };
52 
53 template <typename... Args>
54 struct QConstOverload
55 {
56     template <typename R, typename T>
57     Q_DECL_CONSTEXPR auto operator()(R (T::*ptr)(Args...) const) const Q_DECL_NOTHROW -> decltype(ptr)
58     { return ptr; }
59 
60     template <typename R, typename T>
61     static Q_DECL_CONSTEXPR auto of(R (T::*ptr)(Args...) const) Q_DECL_NOTHROW -> decltype(ptr)
62     { return ptr; }
63 };
64 
65 template <typename... Args>
66 struct QOverload : QConstOverload<Args...>, QNonConstOverload<Args...>
67 {
68     using QConstOverload<Args...>::of;
69     using QConstOverload<Args...>::operator();
70     using QNonConstOverload<Args...>::of;
71     using QNonConstOverload<Args...>::operator();
72 
73     template <typename R>
74     Q_DECL_CONSTEXPR auto operator()(R (*ptr)(Args...)) const Q_DECL_NOTHROW -> decltype(ptr)
75     { return ptr; }
76 
77     template <typename R>
78     static Q_DECL_CONSTEXPR auto of(R (*ptr)(Args...)) Q_DECL_NOTHROW -> decltype(ptr)
79     { return ptr; }
80 };
81 
82 #if defined(__cpp_variable_templates) && __cpp_variable_templates >= 201304 // C++14
83 template <typename... Args> Q_CONSTEXPR Q_DECL_UNUSED QOverload<Args...> qOverload = {};
84 template <typename... Args> Q_CONSTEXPR Q_DECL_UNUSED QConstOverload<Args...> qConstOverload = {};
85 template <typename... Args> Q_CONSTEXPR Q_DECL_UNUSED QNonConstOverload<Args...> qNonConstOverload = {};
86 #endif
87 
88 QT_WARNING_POP
89 
90 #endif // Q_COMPILER_VARIADIC_TEMPLATES
91 #endif // QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
92 
93 #endif // QOVERLOAD_H
94