##// END OF EJS Templates
Remove coverage from windows build...
perrinel -
r76:6f69134168e5
parent child
Show More
@@ -1,38 +1,38
1 /*------------------------------------------------------------------------------
1 /*------------------------------------------------------------------------------
2 -- This file is a part of the QLop Software
2 -- This file is a part of the QLop Software
3 -- Copyright (C) 2015, Plasma Physics Laboratory - CNRS
3 -- Copyright (C) 2015, Plasma Physics Laboratory - CNRS
4 --
4 --
5 -- This program is free software; you can redistribute it and/or modify
5 -- This program is free software; you can redistribute it and/or modify
6 -- it under the terms of the GNU General Public License as published by
6 -- it under the terms of the GNU General Public License as published by
7 -- the Free Software Foundation; either version 2 of the License, or
7 -- the Free Software Foundation; either version 2 of the License, or
8 -- (at your option) any later version.
8 -- (at your option) any later version.
9 --
9 --
10 -- This program is distributed in the hope that it will be useful,
10 -- This program is distributed in the hope that it will be useful,
11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 -- GNU General Public License for more details.
13 -- GNU General Public License for more details.
14 --
14 --
15 -- You should have received a copy of the GNU General Public License
15 -- You should have received a copy of the GNU General Public License
16 -- along with this program; if not, write to the Free Software
16 -- along with this program; if not, write to the Free Software
17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 -------------------------------------------------------------------------------*/
18 -------------------------------------------------------------------------------*/
19 /*-- Author : Alexis Jeandet
19 /*-- Author : Alexis Jeandet
20 -- Mail : alexis.jeandet@member.fsf.org
20 -- Mail : alexis.jeandet@member.fsf.org
21 ----------------------------------------------------------------------------*/
21 ----------------------------------------------------------------------------*/
22 #include "mainwindow.h"
22 #include "MainWindow.h"
23 #include <QProcessEnvironment>
23 #include <QProcessEnvironment>
24 #include <QThread>
24 #include <QThread>
25 #include <SqpApplication.h>
25 #include <SqpApplication.h>
26 #include <qglobal.h>
26 #include <qglobal.h>
27
27
28 int main(int argc, char *argv[])
28 int main(int argc, char *argv[])
29 {
29 {
30 SqpApplication a{argc, argv};
30 SqpApplication a{argc, argv};
31 SqpApplication::setOrganizationName("LPP");
31 SqpApplication::setOrganizationName("LPP");
32 SqpApplication::setOrganizationDomain("lpp.fr");
32 SqpApplication::setOrganizationDomain("lpp.fr");
33 SqpApplication::setApplicationName("SciQLop");
33 SqpApplication::setApplicationName("SciQLop");
34 MainWindow w;
34 MainWindow w;
35 w.show();
35 w.show();
36
36
37 return a.exec();
37 return a.exec();
38 }
38 }
@@ -1,145 +1,147
1
1
2 ## core - CMakeLists.txt
2 ## core - CMakeLists.txt
3 STRING(TOLOWER ${CMAKE_PROJECT_NAME} LIBRARY_PREFFIX)
3 STRING(TOLOWER ${CMAKE_PROJECT_NAME} LIBRARY_PREFFIX)
4 SET(SQPCORE_LIBRARY_NAME "${LIBRARY_PREFFIX}_core${DEBUG_SUFFIX}")
4 SET(SQPCORE_LIBRARY_NAME "${LIBRARY_PREFFIX}_core${DEBUG_SUFFIX}")
5 SET(SOURCES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/")
5 SET(SOURCES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/")
6 SET(INCLUDES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include/")
6 SET(INCLUDES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include/")
7
7
8 # Include core directory
8 # Include core directory
9 include_directories("${INCLUDES_DIR}")
9 include_directories("${INCLUDES_DIR}")
10
10
11 # Set a variable to display a warning in the version files.
11 # Set a variable to display a warning in the version files.
12 SET(SCIQLOP_CMAKE_GENERATION_WARNING "DON'T CHANGE THIS FILE. AUTOGENERATED BY CMAKE.")
12 SET(SCIQLOP_CMAKE_GENERATION_WARNING "DON'T CHANGE THIS FILE. AUTOGENERATED BY CMAKE.")
13 # Generate the version file from the cmake version variables. The version
13 # Generate the version file from the cmake version variables. The version
14 # variables are defined in the cmake/sciqlop_version.cmake file.
14 # variables are defined in the cmake/sciqlop_version.cmake file.
15 CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/resources/Version.h.in"
15 CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/resources/Version.h.in"
16 "${INCLUDES_DIR}/Version.h")
16 "${INCLUDES_DIR}/Version.h")
17 CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/resources/Version.cpp.in"
17 CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/resources/Version.cpp.in"
18 "${SOURCES_DIR}/Version.cpp")
18 "${SOURCES_DIR}/Version.cpp")
19
19
20 # Find dependent modules
20 # Find dependent modules
21 find_package(sciqlop-plugin)
21 find_package(sciqlop-plugin)
22 INCLUDE_DIRECTORIES(${SCIQLOP-PLUGIN_INCLUDE_DIR})
22 INCLUDE_DIRECTORIES(${SCIQLOP-PLUGIN_INCLUDE_DIR})
23
23
24 #
24 #
25 # Find Qt modules
25 # Find Qt modules
26 #
26 #
27 SCIQLOP_FIND_QT(Core)
27 SCIQLOP_FIND_QT(Core)
28
28
29 #
29 #
30 # Compile the library library
30 # Compile the library library
31 #
31 #
32 FILE (GLOB_RECURSE MODULE_SOURCES
32 FILE (GLOB_RECURSE MODULE_SOURCES
33 ${INCLUDES_DIR}/*.h
33 ${INCLUDES_DIR}/*.h
34 ${SOURCES_DIR}/*.c
34 ${SOURCES_DIR}/*.c
35 ${SOURCES_DIR}/*.cpp
35 ${SOURCES_DIR}/*.cpp
36 ${SOURCES_DIR}/*.h)
36 ${SOURCES_DIR}/*.h)
37
37
38 ADD_LIBRARY(${SQPCORE_LIBRARY_NAME} ${MODULE_SOURCES})
38 ADD_LIBRARY(${SQPCORE_LIBRARY_NAME} ${MODULE_SOURCES})
39 set_property(TARGET ${SQPCORE_LIBRARY_NAME} PROPERTY CXX_STANDARD 14)
39 set_property(TARGET ${SQPCORE_LIBRARY_NAME} PROPERTY CXX_STANDARD 14)
40 set_property(TARGET ${SQPCORE_LIBRARY_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
40 set_property(TARGET ${SQPCORE_LIBRARY_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
41 TARGET_LINK_LIBRARIES(${SQPCORE_LIBRARY_NAME})
41 TARGET_LINK_LIBRARIES(${SQPCORE_LIBRARY_NAME})
42 qt5_use_modules(${SQPCORE_LIBRARY_NAME} Core)
42 qt5_use_modules(${SQPCORE_LIBRARY_NAME} Core)
43
43
44 # From cmake documentation: http://www.cmake.org/cmake/help/v3.0/manual/cmake-buildsystem.7.html
44 # From cmake documentation: http://www.cmake.org/cmake/help/v3.0/manual/cmake-buildsystem.7.html
45 # Entries in the COMPILE_DEFINITIONS are prefixed with -D or /D and added to the compile line in an unspecified order.
45 # Entries in the COMPILE_DEFINITIONS are prefixed with -D or /D and added to the compile line in an unspecified order.
46 # The DEFINE_SYMBOL target property is also added as a compile definition as a special convenience case for SHARED and MODULE library targets
46 # The DEFINE_SYMBOL target property is also added as a compile definition as a special convenience case for SHARED and MODULE library targets
47 IF(BUILD_SHARED_LIBS)
47 IF(BUILD_SHARED_LIBS)
48 SET_TARGET_PROPERTIES(${SQPCORE_LIBRARY_NAME} PROPERTIES COMPILE_DEFINITIONS "SCIQLOP_EXPORT")
48 SET_TARGET_PROPERTIES(${SQPCORE_LIBRARY_NAME} PROPERTIES COMPILE_DEFINITIONS "SCIQLOP_EXPORT")
49 ELSE()
49 ELSE()
50 TARGET_COMPILE_DEFINITIONS(${SQPCORE_LIBRARY_NAME} PUBLIC "SCIQLOP_STATIC_LIBRARIES")
50 TARGET_COMPILE_DEFINITIONS(${SQPCORE_LIBRARY_NAME} PUBLIC "SCIQLOP_STATIC_LIBRARIES")
51 ENDIF()
51 ENDIF()
52
52
53 # Set the variable to parent scope so that the other projects can copy the
53 # Set the variable to parent scope so that the other projects can copy the
54 # dependent shared libraries
54 # dependent shared libraries
55 SCIQLOP_SET_TO_PARENT_SCOPE(SQPCORE_LIBRARY_NAME)
55 SCIQLOP_SET_TO_PARENT_SCOPE(SQPCORE_LIBRARY_NAME)
56
56
57 # Copy extern shared libraries to the lib folder
57 # Copy extern shared libraries to the lib folder
58 SCIQLOP_COPY_TO_TARGET(LIBRARY ${SQPCORE_LIBRARY_NAME} ${EXTERN_SHARED_LIBRARIES})
58 SCIQLOP_COPY_TO_TARGET(LIBRARY ${SQPCORE_LIBRARY_NAME} ${EXTERN_SHARED_LIBRARIES})
59
59
60 # Add the files to the list of files to be analyzed
60 # Add the files to the list of files to be analyzed
61 LIST(APPEND CHECKSTYLE_INPUT_FILES ${MODULE_SOURCES})
61 LIST(APPEND CHECKSTYLE_INPUT_FILES ${MODULE_SOURCES})
62 SCIQLOP_SET_TO_PARENT_SCOPE(CHECKSTYLE_INPUT_FILES)
62 SCIQLOP_SET_TO_PARENT_SCOPE(CHECKSTYLE_INPUT_FILES)
63 # Vera++ exclusion files
63 # Vera++ exclusion files
64 LIST(APPEND CHECKSTYLE_EXCLUSION_FILES ${CMAKE_CURRENT_SOURCE_DIR}/vera-exclusions/exclusions.txt)
64 LIST(APPEND CHECKSTYLE_EXCLUSION_FILES ${CMAKE_CURRENT_SOURCE_DIR}/vera-exclusions/exclusions.txt)
65 SCIQLOP_SET_TO_PARENT_SCOPE(CHECKSTYLE_EXCLUSION_FILES)
65 SCIQLOP_SET_TO_PARENT_SCOPE(CHECKSTYLE_EXCLUSION_FILES)
66
66
67 #
67 #
68 # Compile the tests
68 # Compile the tests
69 #
69 #
70 IF(BUILD_TESTS)
70 IF(BUILD_TESTS)
71 INCLUDE_DIRECTORIES(${SOURCES_DIR})
71 INCLUDE_DIRECTORIES(${SOURCES_DIR})
72 FILE (GLOB_RECURSE TESTS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Test*.cpp)
72 FILE (GLOB_RECURSE TESTS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Test*.cpp)
73 FILE (GLOB_RECURSE TESTS_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/Test*.h)
73 FILE (GLOB_RECURSE TESTS_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/Test*.h)
74 SET( TEST_LIBRARIES ${SQPCORE_LIBRARY_NAME})
74 SET( TEST_LIBRARIES ${SQPCORE_LIBRARY_NAME})
75
75
76 SET(TARGETS_COV)
76 SET(TARGETS_COV)
77 FOREACH( testFile ${TESTS_SOURCES} )
77 FOREACH( testFile ${TESTS_SOURCES} )
78 GET_FILENAME_COMPONENT( testDirectory ${testFile} DIRECTORY )
78 GET_FILENAME_COMPONENT( testDirectory ${testFile} DIRECTORY )
79 GET_FILENAME_COMPONENT( testName ${testFile} NAME_WE )
79 GET_FILENAME_COMPONENT( testName ${testFile} NAME_WE )
80
80
81 # Add to the list of sources files all the sources in the same
81 # Add to the list of sources files all the sources in the same
82 # directory that aren't another test
82 # directory that aren't another test
83 FILE (GLOB currentTestSources
83 FILE (GLOB currentTestSources
84 ${testDirectory}/*.c
84 ${testDirectory}/*.c
85 ${testDirectory}/*.cpp
85 ${testDirectory}/*.cpp
86 ${testDirectory}/*.h)
86 ${testDirectory}/*.h)
87 LIST (REMOVE_ITEM currentTestSources ${TESTS_SOURCES})
87 LIST (REMOVE_ITEM currentTestSources ${TESTS_SOURCES})
88 # LIST (REMOVE_ITEM currentTestSources ${TESTS_HEADERS})
88 # LIST (REMOVE_ITEM currentTestSources ${TESTS_HEADERS})
89
89
90 ADD_EXECUTABLE(${testName} ${testFile} ${currentTestSources})
90 ADD_EXECUTABLE(${testName} ${testFile} ${currentTestSources})
91 set_property(TARGET ${testName} PROPERTY CXX_STANDARD 14)
91 set_property(TARGET ${testName} PROPERTY CXX_STANDARD 14)
92 set_property(TARGET ${testName} PROPERTY CXX_STANDARD_REQUIRED ON)
92 set_property(TARGET ${testName} PROPERTY CXX_STANDARD_REQUIRED ON)
93 TARGET_LINK_LIBRARIES( ${testName} ${TEST_LIBRARIES} )
93 TARGET_LINK_LIBRARIES( ${testName} ${TEST_LIBRARIES} )
94 qt5_use_modules(${testName} Test)
94 qt5_use_modules(${testName} Test)
95
95
96 ADD_TEST( NAME ${testName} COMMAND ${testName} )
96 ADD_TEST( NAME ${testName} COMMAND ${testName} )
97
97
98 SCIQLOP_COPY_TO_TARGET(RUNTIME ${testName} ${EXTERN_SHARED_LIBRARIES})
98 SCIQLOP_COPY_TO_TARGET(RUNTIME ${testName} ${EXTERN_SHARED_LIBRARIES})
99 set(Coverage_NAME ${testName})
99 set(Coverage_NAME ${testName})
100 SETUP_TARGET_FOR_COVERAGE(TARGET ${testName}_coverage OUTPUT ${testFile}-path NAME ${testFile} EXECUTABLE ${testName})
100 if(UNIX)
101 LIST( APPEND TARGETS_COV ${testName}_coverage)
101 SETUP_TARGET_FOR_COVERAGE(TARGET ${testName}_coverage OUTPUT ${testFile}-path NAME ${testFile} EXECUTABLE ${testName})
102 LIST( APPEND TARGETS_COV ${testName}_coverage)
103 endif(UNIX)
102
104
103 ENDFOREACH( testFile )
105 ENDFOREACH( testFile )
104
106
105 add_custom_target(coverage)
107 add_custom_target(coverage)
106
108
107 FOREACH( target_cov ${TARGETS_COV} )
109 FOREACH( target_cov ${TARGETS_COV} )
108 add_custom_command(TARGET coverage PRE_BUILD COMMAND make ${target_cov})
110 add_custom_command(TARGET coverage PRE_BUILD COMMAND make ${target_cov})
109 ENDFOREACH( target_cov )
111 ENDFOREACH( target_cov )
110
112
111 LIST(APPEND testFilesToFormat ${TESTS_SOURCES})
113 LIST(APPEND testFilesToFormat ${TESTS_SOURCES})
112 LIST(APPEND testFilesToFormat ${TESTS_HEADERS})
114 LIST(APPEND testFilesToFormat ${TESTS_HEADERS})
113 LIST(APPEND FORMATTING_INPUT_FILES ${testFilesToFormat})
115 LIST(APPEND FORMATTING_INPUT_FILES ${testFilesToFormat})
114 SCIQLOP_SET_TO_PARENT_SCOPE(FORMATTING_INPUT_FILES)
116 SCIQLOP_SET_TO_PARENT_SCOPE(FORMATTING_INPUT_FILES)
115 ENDIF(BUILD_TESTS)
117 ENDIF(BUILD_TESTS)
116
118
117 #
119 #
118 # Set the files that must be formatted by clang-format.
120 # Set the files that must be formatted by clang-format.
119 #
121 #
120 LIST (APPEND FORMATTING_INPUT_FILES ${MODULE_SOURCES})
122 LIST (APPEND FORMATTING_INPUT_FILES ${MODULE_SOURCES})
121 SCIQLOP_SET_TO_PARENT_SCOPE(FORMATTING_INPUT_FILES)
123 SCIQLOP_SET_TO_PARENT_SCOPE(FORMATTING_INPUT_FILES)
122
124
123 #
125 #
124 # Set the directories that doxygen must browse to generate the
126 # Set the directories that doxygen must browse to generate the
125 # documentation.
127 # documentation.
126 #
128 #
127 # Source directories:
129 # Source directories:
128 LIST (APPEND DOXYGEN_INPUT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/docs")
130 LIST (APPEND DOXYGEN_INPUT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/docs")
129 LIST (APPEND DOXYGEN_INPUT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/src")
131 LIST (APPEND DOXYGEN_INPUT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/src")
130 SCIQLOP_SET_TO_PARENT_SCOPE(DOXYGEN_INPUT_DIRS)
132 SCIQLOP_SET_TO_PARENT_SCOPE(DOXYGEN_INPUT_DIRS)
131 # Source directories to exclude from the documentation generation
133 # Source directories to exclude from the documentation generation
132 #LIST (APPEND DOXYGEN_EXCLUDE_PATTERNS "${CMAKE_CURRENT_SOURCE_DIR}/path/to/subdir/*")
134 #LIST (APPEND DOXYGEN_EXCLUDE_PATTERNS "${CMAKE_CURRENT_SOURCE_DIR}/path/to/subdir/*")
133 SCIQLOP_SET_TO_PARENT_SCOPE(DOXYGEN_EXCLUDE_PATTERNS)
135 SCIQLOP_SET_TO_PARENT_SCOPE(DOXYGEN_EXCLUDE_PATTERNS)
134
136
135 #
137 #
136 # Set the directories with the sources to analyze and propagate the
138 # Set the directories with the sources to analyze and propagate the
137 # modification to the parent scope
139 # modification to the parent scope
138 #
140 #
139 # Source directories to analyze:
141 # Source directories to analyze:
140 LIST (APPEND ANALYSIS_INPUT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/src")
142 LIST (APPEND ANALYSIS_INPUT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/src")
141 LIST (APPEND ANALYSIS_INPUT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/tests")
143 LIST (APPEND ANALYSIS_INPUT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/tests")
142 SCIQLOP_SET_TO_PARENT_SCOPE(ANALYSIS_INPUT_DIRS)
144 SCIQLOP_SET_TO_PARENT_SCOPE(ANALYSIS_INPUT_DIRS)
143 # Source directories to exclude from the analysis
145 # Source directories to exclude from the analysis
144 #LIST (APPEND ANALYSIS_EXCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/path/to/subdir")
146 #LIST (APPEND ANALYSIS_EXCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/path/to/subdir")
145 SCIQLOP_SET_TO_PARENT_SCOPE(ANALYSIS_EXCLUDE_DIRS)
147 SCIQLOP_SET_TO_PARENT_SCOPE(ANALYSIS_EXCLUDE_DIRS)
@@ -1,462 +1,460
1 /*
1 /*
2 ====================================================================
2 ====================================================================
3 A Smart Pointer to IMPLementation (i.e. Smart PIMPL or just SPIMPL).
3 A Smart Pointer to IMPLementation (i.e. Smart PIMPL or just SPIMPL).
4 ====================================================================
4 ====================================================================
5
5
6 Version: 1.1
6 Version: 1.1
7
7
8 Latest version:
8 Latest version:
9 https://github.com/oliora/samples/blob/master/spimpl.h
9 https://github.com/oliora/samples/blob/master/spimpl.h
10 Rationale and description:
10 Rationale and description:
11 http://oliora.github.io/2015/12/29/pimpl-and-rule-of-zero.html
11 http://oliora.github.io/2015/12/29/pimpl-and-rule-of-zero.html
12
12
13 Copyright (c) 2015 Andrey Upadyshev (oliora@gmail.com)
13 Copyright (c) 2015 Andrey Upadyshev (oliora@gmail.com)
14
14
15 Distributed under the Boost Software License, Version 1.0.
15 Distributed under the Boost Software License, Version 1.0.
16 See http://www.boost.org/LICENSE_1_0.txt
16 See http://www.boost.org/LICENSE_1_0.txt
17
17
18 Changes history
18 Changes history
19 ---------------
19 ---------------
20 v1.1:
20 v1.1:
21 - auto_ptr support is disabled by default for C++17 compatibility
21 - auto_ptr support is disabled by default for C++17 compatibility
22 v1.0:
22 v1.0:
23 - Released
23 - Released
24 */
24 */
25
25
26 #ifndef SPIMPL_H_
26 #ifndef SPIMPL_H_
27 #define SPIMPL_H_
27 #define SPIMPL_H_
28
28
29 #include <cassert>
29 #include <cassert>
30 #include <memory>
30 #include <memory>
31 #include <type_traits>
31 #include <type_traits>
32
32
33 #if defined _MSC_VER && _MSC_VER < 1900 // MS Visual Studio before VS2015
33 #if defined _MSC_VER && _MSC_VER < 1900 // MS Visual Studio before VS2015
34 #define SPIMPL_NO_CPP11_NOEXCEPT
34 #define SPIMPL_NO_CPP11_NOEXCEPT
35 #define SPIMPL_NO_CPP11_CONSTEXPR
35 #define SPIMPL_NO_CPP11_CONSTEXPR
36 #define SPIMPL_NO_CPP11_DEFAULT_MOVE_SPEC_FUNC
36 #define SPIMPL_NO_CPP11_DEFAULT_MOVE_SPEC_FUNC
37 #endif
37 #endif
38
38
39 #if !defined SPIMPL_NO_CPP11_NOEXCEPT
39 #if !defined SPIMPL_NO_CPP11_NOEXCEPT
40 #define SPIMPL_NOEXCEPT noexcept
40 #define SPIMPL_NOEXCEPT noexcept
41 #else
41 #else
42 #define SPIMPL_NOEXCEPT
42 #define SPIMPL_NOEXCEPT
43 #endif
43 #endif
44
44
45 #if !defined SPIMPL_NO_CPP11_CONSTEXPR
45 #if !defined SPIMPL_NO_CPP11_CONSTEXPR
46 #define SPIMPL_CONSTEXPR constexpr
46 #define SPIMPL_CONSTEXPR constexpr
47 #else
47 #else
48 #define SPIMPL_CONSTEXPR
48 #define SPIMPL_CONSTEXPR
49 #endif
49 #endif
50
50
51 // define SPIMPL_HAS_AUTO_PTR to enable constructor and assignment operator that accept
51 // define SPIMPL_HAS_AUTO_PTR to enable constructor and assignment operator that accept
52 // std::auto_ptr
52 // std::auto_ptr
53 // TODO: auto detect std::auto_ptr support
53 // TODO: auto detect std::auto_ptr support
54
54
55
55
56 namespace spimpl {
56 namespace spimpl {
57 namespace details {
57 namespace details {
58 template <class T>
58 template <class T>
59 T *default_copy(T *src)
59 T *default_copy(T *src)
60 {
60 {
61 static_assert(sizeof(T) > 0, "default_copy cannot copy incomplete type");
61 static_assert(sizeof(T) > 0, "default_copy cannot copy incomplete type");
62 static_assert(!std::is_void<T>::value, "default_copy cannot copy incomplete type");
62 static_assert(!std::is_void<T>::value, "default_copy cannot copy incomplete type");
63 return new T(*src);
63 return new T(*src);
64 }
64 }
65
65
66 template <class T>
66 template <class T>
67 void default_delete(T *p) SPIMPL_NOEXCEPT
67 void default_delete(T *p) SPIMPL_NOEXCEPT
68 {
68 {
69 static_assert(sizeof(T) > 0, "default_delete cannot delete incomplete type");
69 static_assert(sizeof(T) > 0, "default_delete cannot delete incomplete type");
70 static_assert(!std::is_void<T>::value, "default_delete cannot delete incomplete type");
70 static_assert(!std::is_void<T>::value, "default_delete cannot delete incomplete type");
71 delete p;
71 delete p;
72 }
72 }
73
73
74 template <class T>
74 template <class T>
75 struct default_deleter {
75 struct default_deleter {
76 using type = void (*)(T *);
76 using type = void (*)(T *);
77 };
77 };
78
78
79 template <class T>
79 template <class T>
80 using default_deleter_t = typename default_deleter<T>::type;
80 using default_deleter_t = typename default_deleter<T>::type;
81
81
82 template <class T>
82 template <class T>
83 struct default_copier {
83 struct default_copier {
84 using type = T *(*)(T *);
84 using type = T *(*)(T *);
85 };
85 };
86
86
87 template <class T>
87 template <class T>
88 using default_copier_t = typename default_copier<T>::type;
88 using default_copier_t = typename default_copier<T>::type;
89
89
90 template <class T, class D, class C>
90 template <class T, class D, class C>
91 struct is_default_manageable
91 struct is_default_manageable
92 : public std::integral_constant<bool,
92 : public std::integral_constant<bool, std::is_same<D, default_deleter_t<T> >::value
93 std::is_same<D, default_deleter_t<T> >::value
93 && std::is_same<C, default_copier_t<T> >::value> {
94 && std::is_same<C, default_copier_t<T> >::value> {
95 };
94 };
96 }
95 }
97
96
98
97
99 template <class T, class Deleter = details::default_deleter_t<T>,
98 template <class T, class Deleter = details::default_deleter_t<T>,
100 class Copier = details::default_copier_t<T> >
99 class Copier = details::default_copier_t<T> >
101 class impl_ptr {
100 class impl_ptr {
102 private:
101 private:
103 static_assert(!std::is_array<T>::value,
102 static_assert(!std::is_array<T>::value,
104 "impl_ptr specialization for arrays is not implemented");
103 "impl_ptr specialization for arrays is not implemented");
105 struct dummy_t_ {
104 struct dummy_t_ {
106 int dummy__;
105 int dummy__;
107 };
106 };
108
107
109 public:
108 public:
110 using pointer = T *;
109 using pointer = T *;
111 using element_type = T;
110 using element_type = T;
112 using copier_type = typename std::decay<Copier>::type;
111 using copier_type = typename std::decay<Copier>::type;
113 using deleter_type = typename std::decay<Deleter>::type;
112 using deleter_type = typename std::decay<Deleter>::type;
114 using unique_ptr_type = std::unique_ptr<T, deleter_type>;
113 using unique_ptr_type = std::unique_ptr<T, deleter_type>;
115 using is_default_manageable = details::is_default_manageable<T, deleter_type, copier_type>;
114 using is_default_manageable = details::is_default_manageable<T, deleter_type, copier_type>;
116
115
117 SPIMPL_CONSTEXPR impl_ptr() SPIMPL_NOEXCEPT : ptr_(nullptr, deleter_type{}),
116 SPIMPL_CONSTEXPR impl_ptr() SPIMPL_NOEXCEPT : ptr_(nullptr, deleter_type{}),
118 copier_(copier_type{})
117 copier_(copier_type{})
119 {
118 {
120 }
119 }
121
120
122 SPIMPL_CONSTEXPR impl_ptr(std::nullptr_t) SPIMPL_NOEXCEPT : impl_ptr() {}
121 SPIMPL_CONSTEXPR impl_ptr(std::nullptr_t) SPIMPL_NOEXCEPT : impl_ptr() {}
123
122
124 template <class D, class C>
123 template <class D, class C>
125 impl_ptr(pointer p, D &&d, C &&c,
124 impl_ptr(pointer p, D &&d, C &&c,
126 typename std::enable_if<std::is_convertible<D, deleter_type>::value
125 typename std::enable_if<std::is_convertible<D, deleter_type>::value
127 && std::is_convertible<C, copier_type>::value,
126 && std::is_convertible<C, copier_type>::value,
128 dummy_t_>::type
127 dummy_t_>::type
129 = dummy_t_()) SPIMPL_NOEXCEPT : ptr_(std::move(p), std::forward<D>(d)),
128 = dummy_t_()) SPIMPL_NOEXCEPT : ptr_(std::move(p), std::forward<D>(d)),
130 copier_(std::forward<C>(c))
129 copier_(std::forward<C>(c))
131 {
130 {
132 }
131 }
133
132
134 template <class U>
133 template <class U>
135 impl_ptr(U *u,
134 impl_ptr(U *u, typename std::enable_if<std::is_convertible<U *, pointer>::value
136 typename std::enable_if<std::is_convertible<U *, pointer>::value
135 && is_default_manageable::value,
137 && is_default_manageable::value,
136 dummy_t_>::type
138 dummy_t_>::type
137 = dummy_t_()) SPIMPL_NOEXCEPT
139 = dummy_t_()) SPIMPL_NOEXCEPT
140 : impl_ptr(u, &details::default_delete<T>, &details::default_copy<T>)
138 : impl_ptr(u, &details::default_delete<T>, &details::default_copy<T>)
141 {
139 {
142 }
140 }
143
141
144 impl_ptr(const impl_ptr &r) : impl_ptr(r.clone()) {}
142 impl_ptr(const impl_ptr &r) : impl_ptr(r.clone()) {}
145
143
146 #ifndef SPIMPL_NO_CPP11_DEFAULT_MOVE_SPEC_FUNC
144 #ifndef SPIMPL_NO_CPP11_DEFAULT_MOVE_SPEC_FUNC
147 impl_ptr(impl_ptr &&r) SPIMPL_NOEXCEPT = default;
145 impl_ptr(impl_ptr &&r) SPIMPL_NOEXCEPT = default;
148 #else
146 #else
149 impl_ptr(impl_ptr &&r) SPIMPL_NOEXCEPT : ptr_(std::move(r.ptr_)), copier_(std::move(r.copier_))
147 impl_ptr(impl_ptr &&r) SPIMPL_NOEXCEPT : ptr_(std::move(r.ptr_)), copier_(std::move(r.copier_))
150 {
148 {
151 }
149 }
152 #endif
150 #endif
153
151
154 #ifdef SPIMPL_HAS_AUTO_PTR
152 #ifdef SPIMPL_HAS_AUTO_PTR
155 template <class U>
153 template <class U>
156 impl_ptr(std::auto_ptr<U> &&u,
154 impl_ptr(std::auto_ptr<U> &&u, typename std::enable_if<std::is_convertible<U *, pointer>::value
157 typename std::enable_if<std::is_convertible<U *, pointer>::value
155 && is_default_manageable::value,
158 && is_default_manageable::value,
156 dummy_t_>::type
159 dummy_t_>::type
157 = dummy_t_()) SPIMPL_NOEXCEPT
160 = dummy_t_()) SPIMPL_NOEXCEPT : ptr_(u.release(), &details::default_delete<T>),
158 : ptr_(u.release(), &details::default_delete<T>),
161 copier_(&details::default_copy<T>)
159 copier_(&details::default_copy<T>)
162 {
160 {
163 }
161 }
164 #endif
162 #endif
165
163
166 template <class U>
164 template <class U>
167 impl_ptr(std::unique_ptr<U> &&u,
165 impl_ptr(std::unique_ptr<U> &&u,
168 typename std::enable_if<std::is_convertible<U *, pointer>::value
166 typename std::enable_if<std::is_convertible<U *, pointer>::value
169 && is_default_manageable::value,
167 && is_default_manageable::value,
170 dummy_t_>::type
168 dummy_t_>::type
171 = dummy_t_()) SPIMPL_NOEXCEPT : ptr_(u.release(), &details::default_delete<T>),
169 = dummy_t_()) SPIMPL_NOEXCEPT : ptr_(u.release(), &details::default_delete<T>),
172 copier_(&details::default_copy<T>)
170 copier_(&details::default_copy<T>)
173 {
171 {
174 }
172 }
175
173
176 template <class U, class D, class C>
174 template <class U, class D, class C>
177 impl_ptr(std::unique_ptr<U, D> &&u, C &&c,
175 impl_ptr(std::unique_ptr<U, D> &&u, C &&c,
178 typename std::enable_if<std::is_convertible<U *, pointer>::value
176 typename std::enable_if<std::is_convertible<U *, pointer>::value
179 && std::is_convertible<D, deleter_type>::value
177 && std::is_convertible<D, deleter_type>::value
180 && std::is_convertible<C, copier_type>::value,
178 && std::is_convertible<C, copier_type>::value,
181 dummy_t_>::type
179 dummy_t_>::type
182 = dummy_t_()) SPIMPL_NOEXCEPT : ptr_(std::move(u)),
180 = dummy_t_()) SPIMPL_NOEXCEPT : ptr_(std::move(u)),
183 copier_(std::forward<C>(c))
181 copier_(std::forward<C>(c))
184 {
182 {
185 }
183 }
186
184
187 template <class U, class D, class C>
185 template <class U, class D, class C>
188 impl_ptr(impl_ptr<U, D, C> &&u,
186 impl_ptr(impl_ptr<U, D, C> &&u,
189 typename std::enable_if<std::is_convertible<U *, pointer>::value
187 typename std::enable_if<std::is_convertible<U *, pointer>::value
190 && std::is_convertible<D, deleter_type>::value
188 && std::is_convertible<D, deleter_type>::value
191 && std::is_convertible<C, copier_type>::value,
189 && std::is_convertible<C, copier_type>::value,
192 dummy_t_>::type
190 dummy_t_>::type
193 = dummy_t_()) SPIMPL_NOEXCEPT : ptr_(std::move(u.ptr_)),
191 = dummy_t_()) SPIMPL_NOEXCEPT : ptr_(std::move(u.ptr_)),
194 copier_(std::move(u.copier_))
192 copier_(std::move(u.copier_))
195 {
193 {
196 }
194 }
197
195
198 impl_ptr &operator=(const impl_ptr &r)
196 impl_ptr &operator=(const impl_ptr &r)
199 {
197 {
200 if (this == &r)
198 if (this == &r)
201 return *this;
199 return *this;
202
200
203 return operator=(r.clone());
201 return operator=(r.clone());
204 }
202 }
205
203
206 #ifndef SPIMPL_NO_CPP11_DEFAULT_MOVE_SPEC_FUNC
204 #ifndef SPIMPL_NO_CPP11_DEFAULT_MOVE_SPEC_FUNC
207 impl_ptr &operator=(impl_ptr &&r) SPIMPL_NOEXCEPT = default;
205 impl_ptr &operator=(impl_ptr &&r) SPIMPL_NOEXCEPT = default;
208 #else
206 #else
209 impl_ptr &operator=(impl_ptr &&r) SPIMPL_NOEXCEPT
207 impl_ptr &operator=(impl_ptr &&r) SPIMPL_NOEXCEPT
210 {
208 {
211 ptr_ = std::move(r.ptr_);
209 ptr_ = std::move(r.ptr_);
212 copier_ = std::move(r.copier_);
210 copier_ = std::move(r.copier_);
213 return *this;
211 return *this;
214 }
212 }
215 #endif
213 #endif
216
214
217 template <class U, class D, class C>
215 template <class U, class D, class C>
218 typename std::enable_if<std::is_convertible<U *, pointer>::value
216 typename std::enable_if<std::is_convertible<U *, pointer>::value
219 && std::is_convertible<D, deleter_type>::value
217 && std::is_convertible<D, deleter_type>::value
220 && std::is_convertible<C, copier_type>::value,
218 && std::is_convertible<C, copier_type>::value,
221 impl_ptr &>::type
219 impl_ptr &>::type
222 operator=(impl_ptr<U, D, C> &&u) SPIMPL_NOEXCEPT
220 operator=(impl_ptr<U, D, C> &&u) SPIMPL_NOEXCEPT
223 {
221 {
224 ptr_ = std::move(u.ptr_);
222 ptr_ = std::move(u.ptr_);
225 copier_ = std::move(u.copier_);
223 copier_ = std::move(u.copier_);
226 return *this;
224 return *this;
227 }
225 }
228
226
229 template <class U, class D, class C>
227 template <class U, class D, class C>
230 typename std::enable_if<std::is_convertible<U *, pointer>::value
228 typename std::enable_if<std::is_convertible<U *, pointer>::value
231 && std::is_convertible<D, deleter_type>::value
229 && std::is_convertible<D, deleter_type>::value
232 && std::is_convertible<C, copier_type>::value,
230 && std::is_convertible<C, copier_type>::value,
233 impl_ptr &>::type
231 impl_ptr &>::type
234 operator=(const impl_ptr<U, D, C> &u)
232 operator=(const impl_ptr<U, D, C> &u)
235 {
233 {
236 return operator=(u.clone());
234 return operator=(u.clone());
237 }
235 }
238
236
239 //
237 //
240
238
241 #ifdef SPIMPL_HAS_AUTO_PTR
239 #ifdef SPIMPL_HAS_AUTO_PTR
242 template <class U>
240 template <class U>
243 typename std::enable_if<std::is_convertible<U *, pointer>::value
241 typename std::enable_if<std::is_convertible<U *, pointer>::value
244 && is_default_manageable::value,
242 && is_default_manageable::value,
245 impl_ptr &>::type
243 impl_ptr &>::type
246 operator=(std::auto_ptr<U> &&u) SPIMPL_NOEXCEPT
244 operator=(std::auto_ptr<U> &&u) SPIMPL_NOEXCEPT
247 {
245 {
248 return operator=(impl_ptr(std::move(u)));
246 return operator=(impl_ptr(std::move(u)));
249 }
247 }
250 #endif
248 #endif
251
249
252 template <class U>
250 template <class U>
253 typename std::enable_if<std::is_convertible<U *, pointer>::value
251 typename std::enable_if<std::is_convertible<U *, pointer>::value
254 && is_default_manageable::value,
252 && is_default_manageable::value,
255 impl_ptr &>::type
253 impl_ptr &>::type
256 operator=(std::unique_ptr<U> &&u) SPIMPL_NOEXCEPT
254 operator=(std::unique_ptr<U> &&u) SPIMPL_NOEXCEPT
257 {
255 {
258 return operator=(impl_ptr(std::move(u)));
256 return operator=(impl_ptr(std::move(u)));
259 }
257 }
260
258
261 impl_ptr clone() const
259 impl_ptr clone() const
262 {
260 {
263 return impl_ptr(ptr_ ? copier_(ptr_.get()) : nullptr, ptr_.get_deleter(), copier_);
261 return impl_ptr(ptr_ ? copier_(ptr_.get()) : nullptr, ptr_.get_deleter(), copier_);
264 }
262 }
265
263
266 typename std::remove_reference<T>::type &operator*() const { return *ptr_; }
264 typename std::remove_reference<T>::type &operator*() const { return *ptr_; }
267 pointer operator->() const SPIMPL_NOEXCEPT { return get(); }
265 pointer operator->() const SPIMPL_NOEXCEPT { return get(); }
268 pointer get() const SPIMPL_NOEXCEPT { return ptr_.get(); }
266 pointer get() const SPIMPL_NOEXCEPT { return ptr_.get(); }
269
267
270 void swap(impl_ptr &u) SPIMPL_NOEXCEPT
268 void swap(impl_ptr &u) SPIMPL_NOEXCEPT
271 {
269 {
272 using std::swap;
270 using std::swap;
273 ptr_.swap(u.ptr_);
271 ptr_.swap(u.ptr_);
274 swap(copier_, u.copier_);
272 swap(copier_, u.copier_);
275 }
273 }
276
274
277 pointer release() SPIMPL_NOEXCEPT { return ptr_.release(); }
275 pointer release() SPIMPL_NOEXCEPT { return ptr_.release(); }
278
276
279 unique_ptr_type release_unique() SPIMPL_NOEXCEPT { return std::move(ptr_); }
277 unique_ptr_type release_unique() SPIMPL_NOEXCEPT { return std::move(ptr_); }
280
278
281 explicit operator bool() const SPIMPL_NOEXCEPT { return static_cast<bool>(ptr_); }
279 explicit operator bool() const SPIMPL_NOEXCEPT { return static_cast<bool>(ptr_); }
282
280
283 typename std::remove_reference<deleter_type>::type &get_deleter() SPIMPL_NOEXCEPT
281 typename std::remove_reference<deleter_type>::type &get_deleter() SPIMPL_NOEXCEPT
284 {
282 {
285 return ptr_.get_deleter();
283 return ptr_.get_deleter();
286 }
284 }
287 const typename std::remove_reference<deleter_type>::type &get_deleter() const SPIMPL_NOEXCEPT
285 const typename std::remove_reference<deleter_type>::type &get_deleter() const SPIMPL_NOEXCEPT
288 {
286 {
289 return ptr_.get_deleter();
287 return ptr_.get_deleter();
290 }
288 }
291
289
292 typename std::remove_reference<copier_type>::type &get_copier() SPIMPL_NOEXCEPT
290 typename std::remove_reference<copier_type>::type &get_copier() SPIMPL_NOEXCEPT
293 {
291 {
294 return copier_;
292 return copier_;
295 }
293 }
296 const typename std::remove_reference<copier_type>::type &get_copier() const SPIMPL_NOEXCEPT
294 const typename std::remove_reference<copier_type>::type &get_copier() const SPIMPL_NOEXCEPT
297 {
295 {
298 return copier_;
296 return copier_;
299 }
297 }
300
298
301 private:
299 private:
302 unique_ptr_type ptr_;
300 unique_ptr_type ptr_;
303 copier_type copier_;
301 copier_type copier_;
304 };
302 };
305
303
306
304
307 template <class T, class D, class C>
305 template <class T, class D, class C>
308 inline void swap(impl_ptr<T, D, C> &l, impl_ptr<T, D, C> &r) SPIMPL_NOEXCEPT
306 inline void swap(impl_ptr<T, D, C> &l, impl_ptr<T, D, C> &r) SPIMPL_NOEXCEPT
309 {
307 {
310 l.swap(r);
308 l.swap(r);
311 }
309 }
312
310
313
311
314 template <class T1, class D1, class C1, class T2, class D2, class C2>
312 template <class T1, class D1, class C1, class T2, class D2, class C2>
315 inline bool operator==(const impl_ptr<T1, D1, C1> &l, const impl_ptr<T2, D2, C2> &r)
313 inline bool operator==(const impl_ptr<T1, D1, C1> &l, const impl_ptr<T2, D2, C2> &r)
316 {
314 {
317 return l.get() == r.get();
315 return l.get() == r.get();
318 }
316 }
319
317
320 template <class T1, class D1, class C1, class T2, class D2, class C2>
318 template <class T1, class D1, class C1, class T2, class D2, class C2>
321 inline bool operator!=(const impl_ptr<T1, D1, C1> &l, const impl_ptr<T2, D2, C2> &r)
319 inline bool operator!=(const impl_ptr<T1, D1, C1> &l, const impl_ptr<T2, D2, C2> &r)
322 {
320 {
323 return !(l == r);
321 return !(l == r);
324 }
322 }
325
323
326 template <class T1, class D1, class C1, class T2, class D2, class C2>
324 template <class T1, class D1, class C1, class T2, class D2, class C2>
327 inline bool operator<(const impl_ptr<T1, D1, C1> &l, const impl_ptr<T2, D2, C2> &r)
325 inline bool operator<(const impl_ptr<T1, D1, C1> &l, const impl_ptr<T2, D2, C2> &r)
328 {
326 {
329 using P1 = typename impl_ptr<T1, D1, C1>::pointer;
327 using P1 = typename impl_ptr<T1, D1, C1>::pointer;
330 using P2 = typename impl_ptr<T2, D2, C2>::pointer;
328 using P2 = typename impl_ptr<T2, D2, C2>::pointer;
331 using CT = typename std::common_type<P1, P2>::type;
329 using CT = typename std::common_type<P1, P2>::type;
332 return std::less<CT>()(l.get(), r.get());
330 return std::less<CT>()(l.get(), r.get());
333 }
331 }
334
332
335 template <class T1, class D1, class C1, class T2, class D2, class C2>
333 template <class T1, class D1, class C1, class T2, class D2, class C2>
336 inline bool operator>(const impl_ptr<T1, D1, C1> &l, const impl_ptr<T2, D2, C2> &r)
334 inline bool operator>(const impl_ptr<T1, D1, C1> &l, const impl_ptr<T2, D2, C2> &r)
337 {
335 {
338 return r < l;
336 return r < l;
339 }
337 }
340
338
341 template <class T1, class D1, class C1, class T2, class D2, class C2>
339 template <class T1, class D1, class C1, class T2, class D2, class C2>
342 inline bool operator<=(const impl_ptr<T1, D1, C1> &l, const impl_ptr<T2, D2, C2> &r)
340 inline bool operator<=(const impl_ptr<T1, D1, C1> &l, const impl_ptr<T2, D2, C2> &r)
343 {
341 {
344 return !(r < l);
342 return !(r < l);
345 }
343 }
346
344
347 template <class T1, class D1, class C1, class T2, class D2, class C2>
345 template <class T1, class D1, class C1, class T2, class D2, class C2>
348 inline bool operator>=(const impl_ptr<T1, D1, C1> &l, const impl_ptr<T2, D2, C2> &r)
346 inline bool operator>=(const impl_ptr<T1, D1, C1> &l, const impl_ptr<T2, D2, C2> &r)
349 {
347 {
350 return !(l < r);
348 return !(l < r);
351 }
349 }
352
350
353 template <class T, class D, class C>
351 template <class T, class D, class C>
354 inline bool operator==(const impl_ptr<T, D, C> &p, std::nullptr_t) SPIMPL_NOEXCEPT
352 inline bool operator==(const impl_ptr<T, D, C> &p, std::nullptr_t) SPIMPL_NOEXCEPT
355 {
353 {
356 return !p;
354 return !p;
357 }
355 }
358
356
359 template <class T, class D, class C>
357 template <class T, class D, class C>
360 inline bool operator==(std::nullptr_t, const impl_ptr<T, D, C> &p) SPIMPL_NOEXCEPT
358 inline bool operator==(std::nullptr_t, const impl_ptr<T, D, C> &p) SPIMPL_NOEXCEPT
361 {
359 {
362 return !p;
360 return !p;
363 }
361 }
364
362
365 template <class T, class D, class C>
363 template <class T, class D, class C>
366 inline bool operator!=(const impl_ptr<T, D, C> &p, std::nullptr_t) SPIMPL_NOEXCEPT
364 inline bool operator!=(const impl_ptr<T, D, C> &p, std::nullptr_t) SPIMPL_NOEXCEPT
367 {
365 {
368 return static_cast<bool>(p);
366 return static_cast<bool>(p);
369 }
367 }
370
368
371 template <class T, class D, class C>
369 template <class T, class D, class C>
372 inline bool operator!=(std::nullptr_t, const impl_ptr<T, D, C> &p) SPIMPL_NOEXCEPT
370 inline bool operator!=(std::nullptr_t, const impl_ptr<T, D, C> &p) SPIMPL_NOEXCEPT
373 {
371 {
374 return static_cast<bool>(p);
372 return static_cast<bool>(p);
375 }
373 }
376
374
377 template <class T, class D, class C>
375 template <class T, class D, class C>
378 inline bool operator<(const impl_ptr<T, D, C> &l, std::nullptr_t)
376 inline bool operator<(const impl_ptr<T, D, C> &l, std::nullptr_t)
379 {
377 {
380 using P = typename impl_ptr<T, D, C>::pointer;
378 using P = typename impl_ptr<T, D, C>::pointer;
381 return std::less<P>()(l.get(), nullptr);
379 return std::less<P>()(l.get(), nullptr);
382 }
380 }
383
381
384 template <class T, class D, class C>
382 template <class T, class D, class C>
385 inline bool operator<(std::nullptr_t, const impl_ptr<T, D, C> &p)
383 inline bool operator<(std::nullptr_t, const impl_ptr<T, D, C> &p)
386 {
384 {
387 using P = typename impl_ptr<T, D, C>::pointer;
385 using P = typename impl_ptr<T, D, C>::pointer;
388 return std::less<P>()(nullptr, p.get());
386 return std::less<P>()(nullptr, p.get());
389 }
387 }
390
388
391 template <class T, class D, class C>
389 template <class T, class D, class C>
392 inline bool operator>(const impl_ptr<T, D, C> &p, std::nullptr_t)
390 inline bool operator>(const impl_ptr<T, D, C> &p, std::nullptr_t)
393 {
391 {
394 return nullptr < p;
392 return nullptr < p;
395 }
393 }
396
394
397 template <class T, class D, class C>
395 template <class T, class D, class C>
398 inline bool operator>(std::nullptr_t, const impl_ptr<T, D, C> &p)
396 inline bool operator>(std::nullptr_t, const impl_ptr<T, D, C> &p)
399 {
397 {
400 return p < nullptr;
398 return p < nullptr;
401 }
399 }
402
400
403 template <class T, class D, class C>
401 template <class T, class D, class C>
404 inline bool operator<=(const impl_ptr<T, D, C> &p, std::nullptr_t)
402 inline bool operator<=(const impl_ptr<T, D, C> &p, std::nullptr_t)
405 {
403 {
406 return !(nullptr < p);
404 return !(nullptr < p);
407 }
405 }
408
406
409 template <class T, class D, class C>
407 template <class T, class D, class C>
410 inline bool operator<=(std::nullptr_t, const impl_ptr<T, D, C> &p)
408 inline bool operator<=(std::nullptr_t, const impl_ptr<T, D, C> &p)
411 {
409 {
412 return !(p < nullptr);
410 return !(p < nullptr);
413 }
411 }
414
412
415 template <class T, class D, class C>
413 template <class T, class D, class C>
416 inline bool operator>=(const impl_ptr<T, D, C> &p, std::nullptr_t)
414 inline bool operator>=(const impl_ptr<T, D, C> &p, std::nullptr_t)
417 {
415 {
418 return !(p < nullptr);
416 return !(p < nullptr);
419 }
417 }
420
418
421 template <class T, class D, class C>
419 template <class T, class D, class C>
422 inline bool operator>=(std::nullptr_t, const impl_ptr<T, D, C> &p)
420 inline bool operator>=(std::nullptr_t, const impl_ptr<T, D, C> &p)
423 {
421 {
424 return !(nullptr < p);
422 return !(nullptr < p);
425 }
423 }
426
424
427
425
428 template <class T, class... Args>
426 template <class T, class... Args>
429 inline impl_ptr<T> make_impl(Args &&... args)
427 inline impl_ptr<T> make_impl(Args &&... args)
430 {
428 {
431 return impl_ptr<T>(new T(std::forward<Args>(args)...), &details::default_delete<T>,
429 return impl_ptr<T>(new T(std::forward<Args>(args)...), &details::default_delete<T>,
432 &details::default_copy<T>);
430 &details::default_copy<T>);
433 }
431 }
434
432
435
433
436 // Helpers to manage unique impl, stored in std::unique_ptr
434 // Helpers to manage unique impl, stored in std::unique_ptr
437
435
438 template <class T, class Deleter = void (*)(T *)>
436 template <class T, class Deleter = void (*)(T *)>
439 using unique_impl_ptr = std::unique_ptr<T, Deleter>;
437 using unique_impl_ptr = std::unique_ptr<T, Deleter>;
440
438
441 template <class T, class... Args>
439 template <class T, class... Args>
442 inline unique_impl_ptr<T> make_unique_impl(Args &&... args)
440 inline unique_impl_ptr<T> make_unique_impl(Args &&... args)
443 {
441 {
444 static_assert(!std::is_array<T>::value, "unique_impl_ptr does not support arrays");
442 static_assert(!std::is_array<T>::value, "unique_impl_ptr does not support arrays");
445 return unique_impl_ptr<T>(new T(std::forward<Args>(args)...), &details::default_delete<T>);
443 return unique_impl_ptr<T>(new T(std::forward<Args>(args)...), &details::default_delete<T>);
446 }
444 }
447 }
445 }
448
446
449 namespace std {
447 namespace std {
450 template <class T, class D, class C>
448 template <class T, class D, class C>
451 struct hash<spimpl::impl_ptr<T, D, C> > {
449 struct hash<spimpl::impl_ptr<T, D, C> > {
452 using argument_type = spimpl::impl_ptr<T, D, C>;
450 using argument_type = spimpl::impl_ptr<T, D, C>;
453 using result_type = size_t;
451 using result_type = size_t;
454
452
455 result_type operator()(const argument_type &p) const SPIMPL_NOEXCEPT
453 result_type operator()(const argument_type &p) const SPIMPL_NOEXCEPT
456 {
454 {
457 return hash<typename argument_type::pointer>()(p.get());
455 return hash<typename argument_type::pointer>()(p.get());
458 }
456 }
459 };
457 };
460 }
458 }
461
459
462 #endif // SPIMPL_H_
460 #endif // SPIMPL_H_
@@ -1,78 +1,78
1 #include <DataSource/DataSourceController.h>
1 #include <DataSource/DataSourceController.h>
2 #include <DataSource/DataSourceItem.h>
2 #include <DataSource/DataSourceItem.h>
3
3
4 #include <QMutex>
4 #include <QMutex>
5 #include <QThread>
5 #include <QThread>
6
6
7 #include <QDir>
7 #include <QDir>
8 #include <QStandardPaths>
8 #include <QStandardPaths>
9
9
10 Q_LOGGING_CATEGORY(LOG_DataSourceController, "DataSourceController")
10 Q_LOGGING_CATEGORY(LOG_DataSourceController, "DataSourceController")
11
11
12 class DataSourceController::DataSourceControllerPrivate {
12 class DataSourceController::DataSourceControllerPrivate {
13 public:
13 public:
14 QMutex m_WorkingMutex;
14 QMutex m_WorkingMutex;
15 /// Data sources registered
15 /// Data sources registered
16 QHash<QUuid, QString> m_DataSources;
16 QHash<QUuid, QString> m_DataSources;
17 /// Data sources structures
17 /// Data sources structures
18 std::map<QUuid, std::unique_ptr<DataSourceItem> > m_DataSourceItems;
18 std::map<QUuid, std::unique_ptr<DataSourceItem> > m_DataSourceItems;
19 };
19 };
20
20
21 DataSourceController::DataSourceController(QObject *parent)
21 DataSourceController::DataSourceController(QObject *parent)
22 : impl{spimpl::make_unique_impl<DataSourceControllerPrivate>()}
22 : impl{spimpl::make_unique_impl<DataSourceControllerPrivate>()}
23 {
23 {
24 qCDebug(LOG_DataSourceController())
24 qCDebug(LOG_DataSourceController()) << tr("DataSourceController construction")
25 << tr("DataSourceController construction") << QThread::currentThread();
25 << QThread::currentThread();
26 }
26 }
27
27
28 DataSourceController::~DataSourceController()
28 DataSourceController::~DataSourceController()
29 {
29 {
30 qCDebug(LOG_DataSourceController())
30 qCDebug(LOG_DataSourceController()) << tr("DataSourceController destruction")
31 << tr("DataSourceController destruction") << QThread::currentThread();
31 << QThread::currentThread();
32 this->waitForFinish();
32 this->waitForFinish();
33 }
33 }
34
34
35 QUuid DataSourceController::registerDataSource(const QString &dataSourceName) noexcept
35 QUuid DataSourceController::registerDataSource(const QString &dataSourceName) noexcept
36 {
36 {
37 auto dataSourceUid = QUuid::createUuid();
37 auto dataSourceUid = QUuid::createUuid();
38 impl->m_DataSources.insert(dataSourceUid, dataSourceName);
38 impl->m_DataSources.insert(dataSourceUid, dataSourceName);
39
39
40 return dataSourceUid;
40 return dataSourceUid;
41 }
41 }
42
42
43 void DataSourceController::setDataSourceItem(
43 void DataSourceController::setDataSourceItem(
44 const QUuid &dataSourceUid, std::unique_ptr<DataSourceItem> dataSourceItem) noexcept
44 const QUuid &dataSourceUid, std::unique_ptr<DataSourceItem> dataSourceItem) noexcept
45 {
45 {
46 if (impl->m_DataSources.contains(dataSourceUid)) {
46 if (impl->m_DataSources.contains(dataSourceUid)) {
47 impl->m_DataSourceItems.insert(std::make_pair(dataSourceUid, std::move(dataSourceItem)));
47 impl->m_DataSourceItems.insert(std::make_pair(dataSourceUid, std::move(dataSourceItem)));
48
48
49 // Retrieves the data source item to emit the signal with it
49 // Retrieves the data source item to emit the signal with it
50 auto it = impl->m_DataSourceItems.find(dataSourceUid);
50 auto it = impl->m_DataSourceItems.find(dataSourceUid);
51 if (it != impl->m_DataSourceItems.end()) {
51 if (it != impl->m_DataSourceItems.end()) {
52 emit dataSourceItemSet(*it->second);
52 emit dataSourceItemSet(*it->second);
53 }
53 }
54 }
54 }
55 else {
55 else {
56 qCWarning(LOG_DataSourceController()) << tr("Can't set data source item for uid %1 : no "
56 qCWarning(LOG_DataSourceController()) << tr("Can't set data source item for uid %1 : no "
57 "data source has been registered with the uid")
57 "data source has been registered with the uid")
58 .arg(dataSourceUid.toString());
58 .arg(dataSourceUid.toString());
59 }
59 }
60 }
60 }
61
61
62 void DataSourceController::initialize()
62 void DataSourceController::initialize()
63 {
63 {
64 qCDebug(LOG_DataSourceController())
64 qCDebug(LOG_DataSourceController()) << tr("DataSourceController init")
65 << tr("DataSourceController init") << QThread::currentThread();
65 << QThread::currentThread();
66 impl->m_WorkingMutex.lock();
66 impl->m_WorkingMutex.lock();
67 qCDebug(LOG_DataSourceController()) << tr("DataSourceController init END");
67 qCDebug(LOG_DataSourceController()) << tr("DataSourceController init END");
68 }
68 }
69
69
70 void DataSourceController::finalize()
70 void DataSourceController::finalize()
71 {
71 {
72 impl->m_WorkingMutex.unlock();
72 impl->m_WorkingMutex.unlock();
73 }
73 }
74
74
75 void DataSourceController::waitForFinish()
75 void DataSourceController::waitForFinish()
76 {
76 {
77 QMutexLocker locker{&impl->m_WorkingMutex};
77 QMutexLocker locker{&impl->m_WorkingMutex};
78 }
78 }
@@ -1,46 +1,46
1 #include <Visualization/VisualizationController.h>
1 #include <Visualization/VisualizationController.h>
2
2
3 #include <QMutex>
3 #include <QMutex>
4 #include <QThread>
4 #include <QThread>
5
5
6 #include <QDir>
6 #include <QDir>
7 #include <QStandardPaths>
7 #include <QStandardPaths>
8
8
9 Q_LOGGING_CATEGORY(LOG_VisualizationController, "VisualizationController")
9 Q_LOGGING_CATEGORY(LOG_VisualizationController, "VisualizationController")
10
10
11 class VisualizationController::VisualizationControllerPrivate {
11 class VisualizationController::VisualizationControllerPrivate {
12 public:
12 public:
13 QMutex m_WorkingMutex;
13 QMutex m_WorkingMutex;
14 };
14 };
15
15
16 VisualizationController::VisualizationController(QObject *parent)
16 VisualizationController::VisualizationController(QObject *parent)
17 : impl{spimpl::make_unique_impl<VisualizationControllerPrivate>()}
17 : impl{spimpl::make_unique_impl<VisualizationControllerPrivate>()}
18 {
18 {
19 qCDebug(LOG_VisualizationController())
19 qCDebug(LOG_VisualizationController()) << tr("VisualizationController construction")
20 << tr("VisualizationController construction") << QThread::currentThread();
20 << QThread::currentThread();
21 }
21 }
22
22
23 VisualizationController::~VisualizationController()
23 VisualizationController::~VisualizationController()
24 {
24 {
25 qCDebug(LOG_VisualizationController())
25 qCDebug(LOG_VisualizationController()) << tr("VisualizationController destruction")
26 << tr("VisualizationController destruction") << QThread::currentThread();
26 << QThread::currentThread();
27 this->waitForFinish();
27 this->waitForFinish();
28 }
28 }
29
29
30 void VisualizationController::initialize()
30 void VisualizationController::initialize()
31 {
31 {
32 qCDebug(LOG_VisualizationController())
32 qCDebug(LOG_VisualizationController()) << tr("VisualizationController init")
33 << tr("VisualizationController init") << QThread::currentThread();
33 << QThread::currentThread();
34 impl->m_WorkingMutex.lock();
34 impl->m_WorkingMutex.lock();
35 qCDebug(LOG_VisualizationController()) << tr("VisualizationController init END");
35 qCDebug(LOG_VisualizationController()) << tr("VisualizationController init END");
36 }
36 }
37
37
38 void VisualizationController::finalize()
38 void VisualizationController::finalize()
39 {
39 {
40 impl->m_WorkingMutex.unlock();
40 impl->m_WorkingMutex.unlock();
41 }
41 }
42
42
43 void VisualizationController::waitForFinish()
43 void VisualizationController::waitForFinish()
44 {
44 {
45 QMutexLocker locker{&impl->m_WorkingMutex};
45 QMutexLocker locker{&impl->m_WorkingMutex};
46 }
46 }
General Comments 0
You need to be logged in to leave comments. Login now