From e5c7999f087c5b9fc78eb8ac8a701ab191695bd6 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Tue, 24 Mar 2020 15:02:13 +0100 Subject: [PATCH 01/30] Start adding runtime type info to problem. --- include/pagmo/problem.hpp | 12 +++++++++++- src/problem.cpp | 7 +++++++ tests/problem.cpp | 8 ++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/include/pagmo/problem.hpp b/include/pagmo/problem.hpp index f763f624b..8a172d9cc 100644 --- a/include/pagmo/problem.hpp +++ b/include/pagmo/problem.hpp @@ -35,6 +35,7 @@ see https://www.gnu.org/licenses/. */ #include #include #include +#include #include #include #include @@ -43,8 +44,8 @@ see https://www.gnu.org/licenses/. */ #include #include -#include #include +#include #include #include #include @@ -538,6 +539,7 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS prob_inner_base { virtual std::string get_name() const = 0; virtual std::string get_extra_info() const = 0; virtual thread_safety get_thread_safety() const = 0; + virtual std::type_index get_type_index() const = 0; template void serialize(Archive &, unsigned) { @@ -908,6 +910,11 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS prob_inner final : prob_inner_base { { return thread_safety::basic; } + // Get the type at runtime. + virtual std::type_index get_type_index() const override final + { + return std::type_index(typeid(T)); + } // Serialization. template void serialize(Archive &ar, unsigned) @@ -1591,6 +1598,9 @@ class PAGMO_DLL_PUBLIC problem // Check if the problem is in a valid state. bool is_valid() const; + // Get the type at runtime. + std::type_index get_type_index() const; + /// Save to archive. /** * This method will save \p this into the archive \p ar. diff --git a/src/problem.cpp b/src/problem.cpp index 02b21417b..42693cc6c 100644 --- a/src/problem.cpp +++ b/src/problem.cpp @@ -35,6 +35,7 @@ see https://www.gnu.org/licenses/. */ #include #include #include +#include #include #include @@ -741,6 +742,12 @@ bool problem::is_valid() const return static_cast(m_ptr); } +// Get the type at runtime. +std::type_index problem::get_type_index() const +{ + return ptr()->get_type_index(); +} + /// Streaming operator /** * This function will stream to \p os a human-readable representation of the input diff --git a/tests/problem.cpp b/tests/problem.cpp index 1227d200f..d96b4a219 100644 --- a/tests/problem.cpp +++ b/tests/problem.cpp @@ -1593,3 +1593,11 @@ BOOST_AUTO_TEST_CASE(generic_assignment) BOOST_CHECK((!std::is_assignable::value)); BOOST_CHECK((!std::is_assignable::value)); } + +BOOST_AUTO_TEST_CASE(type_index) +{ + problem p0; + std::cout << p0.get_type_index().name() << '\n'; + p0 = problem{grad_p_override{}}; + std::cout << p0.get_type_index().name() << '\n'; +} From e972e752e2a2db08ce4e68df6015e93767c2a15e Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Wed, 25 Mar 2020 09:24:59 +0100 Subject: [PATCH 02/30] Add demangling capabilities. [skip ci] --- CMakeLists.txt | 1 + include/pagmo/detail/type_name.hpp | 85 ++++++++++++++++++++++++++++++ include/pagmo/problem.hpp | 3 +- src/detail/type_name.cpp | 71 +++++++++++++++++++++++++ src/problem.cpp | 2 + tests/problem.cpp | 8 +-- 6 files changed, 166 insertions(+), 4 deletions(-) create mode 100644 include/pagmo/detail/type_name.hpp create mode 100644 src/detail/type_name.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b8cd12be..5e68e3eee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -208,6 +208,7 @@ set(PAGMO_SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/detail/task_queue.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/detail/prime_numbers.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/detail/gte_getter.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/src/detail/type_name.cpp" ) # Some compilers choke on the cec2013/2014 data arrays. diff --git a/include/pagmo/detail/type_name.hpp b/include/pagmo/detail/type_name.hpp new file mode 100644 index 000000000..62cd7c10b --- /dev/null +++ b/include/pagmo/detail/type_name.hpp @@ -0,0 +1,85 @@ +/* Copyright 2017-2020 PaGMO development team + +This file is part of the PaGMO library. + +The PaGMO library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 3 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The PaGMO library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the PaGMO library. If not, +see https://www.gnu.org/licenses/. */ + +#ifndef PAGMO_DETAIL_TYPE_NAME_HPP +#define PAGMO_DETAIL_TYPE_NAME_HPP + +#include +#include +#include + +#include + +namespace pagmo +{ + +namespace detail +{ + +PAGMO_DLL_PUBLIC std::string demangle_from_typeid(const char *); + +// Determine the name of the type T at runtime. +template +inline std::string type_name() +{ + // Get the demangled name without cvref. + auto ret + = demangle_from_typeid(typeid(typename std::remove_cv::type>::type).name()); + + // Redecorate it with cv qualifiers. + constexpr unsigned flag = unsigned(std::is_const::type>::value) + + (unsigned(std::is_volatile::type>::value) << 1); + switch (flag) { + case 0u: + // NOTE: handle this explicitly to keep compiler warnings at bay. + break; + case 1u: + ret += " const"; + break; + case 2u: + ret += " volatile"; + break; + case 3u: + ret += " const volatile"; + } + + // Re-add the reference, if necessary. + if (std::is_lvalue_reference::value) { + ret += " &"; + } else if (std::is_rvalue_reference::value) { + ret += " &&"; + } + + return ret; +} + +} // namespace detail + +} // namespace pagmo + +#endif diff --git a/include/pagmo/problem.hpp b/include/pagmo/problem.hpp index 8a172d9cc..60a394902 100644 --- a/include/pagmo/problem.hpp +++ b/include/pagmo/problem.hpp @@ -45,6 +45,7 @@ see https://www.gnu.org/licenses/. */ #include #include +#include #include #include #include @@ -888,7 +889,7 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS prob_inner final : prob_inner_base { template ::value, int> = 0> static std::string get_name_impl(const U &) { - return typeid(U).name(); + return detail::type_name(); } template ::value, int> = 0> static std::string get_extra_info_impl(const U &value) diff --git a/src/detail/type_name.cpp b/src/detail/type_name.cpp new file mode 100644 index 000000000..e4bf5c3cb --- /dev/null +++ b/src/detail/type_name.cpp @@ -0,0 +1,71 @@ +/* Copyright 2017-2020 PaGMO development team + +This file is part of the PaGMO library. + +The PaGMO library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 3 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The PaGMO library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the PaGMO library. If not, +see https://www.gnu.org/licenses/. */ + +#include + +#if defined(__GNUC__) || (defined(__clang__) && !defined(_MSC_VER)) + +// GCC demangle. This is available also for clang, both with libstdc++ and libc++. +#include +#include +#include + +#endif + +#include + +namespace pagmo +{ + +namespace detail +{ + +std::string demangle_from_typeid(const char *s) +{ +#if defined(__GNUC__) || (defined(__clang__) && !defined(_MSC_VER)) + // NOTE: wrap std::free() in a local lambda, so we avoid + // potential ambiguities when taking the address of std::free(). + // See: + // https://stackoverflow.com/questions/27440953/stdunique-ptr-for-c-functions-that-need-free + auto deleter = [](void *ptr) { std::free(ptr); }; + + // NOTE: abi::__cxa_demangle will return a pointer allocated by std::malloc, which we will delete via std::free(). + std::unique_ptr res{::abi::__cxa_demangle(s, nullptr, nullptr, nullptr), deleter}; + + // NOTE: return the original string if demangling fails. + return res ? std::string(res.get()) : std::string(s); +#else + // If no demangling is available, just return the mangled name. + // NOTE: MSVC already returns the demangled name from typeid. + return std::string(s); +#endif +} + +} // namespace detail + +} // namespace pagmo diff --git a/src/problem.cpp b/src/problem.cpp index 42693cc6c..a8e57cc58 100644 --- a/src/problem.cpp +++ b/src/problem.cpp @@ -42,6 +42,7 @@ see https://www.gnu.org/licenses/. */ #include #include +#include #include #include #include @@ -766,6 +767,7 @@ std::ostream &operator<<(std::ostream &os, const problem &p) if (p.is_stochastic()) { stream(os, " [stochastic]"); } + os << "\n\tC++ class name: " << detail::demangle_from_typeid(p.get_type_index().name()) << '\n'; os << "\n\tGlobal dimension:\t\t\t" << p.get_nx() << '\n'; os << "\tInteger dimension:\t\t\t" << p.get_nix() << '\n'; os << "\tFitness dimension:\t\t\t" << p.get_nf() << '\n'; diff --git a/tests/problem.cpp b/tests/problem.cpp index d96b4a219..a4d2bc26a 100644 --- a/tests/problem.cpp +++ b/tests/problem.cpp @@ -36,12 +36,14 @@ see https://www.gnu.org/licenses/. */ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -714,7 +716,7 @@ BOOST_AUTO_TEST_CASE(problem_getters_test) BOOST_CHECK(p1.get_name() == "A base toy problem"); BOOST_CHECK(p1.get_extra_info() == "Nothing to report"); // Default - BOOST_CHECK(p3.get_name() == typeid(*p3.extract()).name()); + BOOST_CHECK(p3.get_name() == detail::demangle_from_typeid(typeid(*p3.extract()).name())); BOOST_CHECK(p3.get_extra_info() == ""); } @@ -1597,7 +1599,7 @@ BOOST_AUTO_TEST_CASE(generic_assignment) BOOST_AUTO_TEST_CASE(type_index) { problem p0; - std::cout << p0.get_type_index().name() << '\n'; + std::cout << p0 << '\n'; p0 = problem{grad_p_override{}}; - std::cout << p0.get_type_index().name() << '\n'; + std::cout << p0 << '\n'; } From 5b081cf6bff9d82a51008b3d349b688864a9e049 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Thu, 26 Mar 2020 21:22:50 +0100 Subject: [PATCH 03/30] Experiment with alternative extract() implementation. [skip ci] --- include/pagmo/problem.hpp | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/include/pagmo/problem.hpp b/include/pagmo/problem.hpp index 60a394902..f1a1703ec 100644 --- a/include/pagmo/problem.hpp +++ b/include/pagmo/problem.hpp @@ -541,6 +541,8 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS prob_inner_base { virtual std::string get_extra_info() const = 0; virtual thread_safety get_thread_safety() const = 0; virtual std::type_index get_type_index() const = 0; + virtual const void *get_void_ptr() const = 0; + virtual void *get_void_ptr() = 0; template void serialize(Archive &, unsigned) { @@ -916,6 +918,14 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS prob_inner final : prob_inner_base { { return std::type_index(typeid(T)); } + virtual const void *get_void_ptr() const override final + { + return &m_value; + } + virtual void *get_void_ptr() override final + { + return &m_value; + } // Serialization. template void serialize(Archive &ar, unsigned) @@ -1165,8 +1175,13 @@ class PAGMO_DLL_PUBLIC problem template const T *extract() const noexcept { - auto p = dynamic_cast *>(ptr()); - return p == nullptr ? nullptr : &(p->m_value); + // auto p = dynamic_cast *>(ptr()); + // return p == nullptr ? nullptr : &(p->m_value); + if (get_type_index().name() == typeid(T).name()) { + return static_cast(ptr()->get_void_ptr()); + } else { + return nullptr; + } } /// Extract a pointer to the UDP used for construction. @@ -1195,8 +1210,13 @@ class PAGMO_DLL_PUBLIC problem template T *extract() noexcept { - auto p = dynamic_cast *>(ptr()); - return p == nullptr ? nullptr : &(p->m_value); + // auto p = dynamic_cast *>(ptr()); + // return p == nullptr ? nullptr : &(p->m_value); + if (get_type_index().name() == typeid(T).name()) { + return static_cast(ptr()->get_void_ptr()); + } else { + return nullptr; + } } /// Check if the UDP used for construction is of type \p T. From 754325755459d9e75cb8033e34fd8977a815ac4b Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Fri, 27 Mar 2020 10:07:13 +0100 Subject: [PATCH 04/30] Initial WIP. --- config.hpp.in | 13 ++++ include/pagmo/detail/typeid_name_extract.hpp | 69 ++++++++++++++++++ include/pagmo/problem.hpp | 73 ++++++++++++++++---- include/pagmo/problems/decompose.hpp | 23 +++++- include/pagmo/problems/translate.hpp | 23 +++++- include/pagmo/problems/unconstrain.hpp | 23 +++++- include/pagmo/rng.hpp | 10 ++- src/problem.cpp | 23 +++++- src/problems/decompose.cpp | 21 ------ src/problems/translate.cpp | 21 ------ src/problems/unconstrain.cpp | 21 ------ src/rng.cpp | 8 --- 12 files changed, 235 insertions(+), 93 deletions(-) create mode 100644 include/pagmo/detail/typeid_name_extract.hpp diff --git a/config.hpp.in b/config.hpp.in index f831454b6..0708b4f88 100644 --- a/config.hpp.in +++ b/config.hpp.in @@ -29,6 +29,10 @@ see https://www.gnu.org/licenses/. */ #ifndef PAGMO_CONFIG_HPP #define PAGMO_CONFIG_HPP +// NOTE: include this so that we can +// detect _LIBCPP_VERSION below. +#include + // Start of defines instantiated by CMake. // clang-format off #define PAGMO_VERSION "@pagmo_VERSION@" @@ -54,4 +58,13 @@ see https://www.gnu.org/licenses/. */ #endif +#if defined(__clang__) && defined(_LIBCPP_VERSION) + +// When using clang + libc++, prefer the name-based +// extract() implementation for UDx classes. See +// the explanation in typeid_name_extract.hpp. +#define PAGMO_PREFER_TYPEID_NAME_EXTRACT + +#endif + #endif diff --git a/include/pagmo/detail/typeid_name_extract.hpp b/include/pagmo/detail/typeid_name_extract.hpp new file mode 100644 index 000000000..3e6ca45c5 --- /dev/null +++ b/include/pagmo/detail/typeid_name_extract.hpp @@ -0,0 +1,69 @@ +/* Copyright 2017-2020 PaGMO development team + +This file is part of the PaGMO library. + +The PaGMO library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 3 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The PaGMO library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the PaGMO library. If not, +see https://www.gnu.org/licenses/. */ + +#ifndef PAGMO_DETAIL_TYPEID_NAME_EXTRACT_HPP +#define PAGMO_DETAIL_TYPEID_NAME_EXTRACT_HPP + +#include +#include +#include + +namespace pagmo +{ + +namespace detail +{ + +// This is an implementation of the extract() functionality +// for UDx classes based on the name() of the UDx C++ type, +// as returned by typeid().name(). This is needed +// because the dynamic_cast() used in the +// usual extract() implementations can fail on some +// compiler/platform/stdlib implementations +// when crossing boundaries between dlopened() +// modules. See: +// https://github.com/pybind/pybind11/issues/912#issuecomment-310157016 +// https://bugs.llvm.org/show_bug.cgi?id=33542 +template +inline typename std::conditional::value, const T *, T *>::type typeid_name_extract(C &class_inst) +{ + if (std::strcmp(class_inst.get_type_index().name(), typeid(T).name())) { + // The names differ, return null. + return nullptr; + } else { + // The names match, cast to the correct type and return. + return static_cast::value, const T *, T *>::type>( + class_inst.get_void_ptr()); + } +} + +} // namespace detail + +} // namespace pagmo + +#endif diff --git a/include/pagmo/problem.hpp b/include/pagmo/problem.hpp index f1a1703ec..2967bc957 100644 --- a/include/pagmo/problem.hpp +++ b/include/pagmo/problem.hpp @@ -43,9 +43,11 @@ see https://www.gnu.org/licenses/. */ #include #include +#include #include #include #include +#include #include #include #include @@ -918,6 +920,7 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS prob_inner final : prob_inner_base { { return std::type_index(typeid(T)); } + // Raw getters for the internal instance. virtual const void *get_void_ptr() const override final { return &m_value; @@ -1175,13 +1178,12 @@ class PAGMO_DLL_PUBLIC problem template const T *extract() const noexcept { - // auto p = dynamic_cast *>(ptr()); - // return p == nullptr ? nullptr : &(p->m_value); - if (get_type_index().name() == typeid(T).name()) { - return static_cast(ptr()->get_void_ptr()); - } else { - return nullptr; - } +#if defined(PAGMO_PREFER_TYPEID_NAME_EXTRACT) + return detail::typeid_name_extract(*this); +#else + auto p = dynamic_cast *>(ptr()); + return p == nullptr ? nullptr : &(p->m_value); +#endif } /// Extract a pointer to the UDP used for construction. @@ -1210,13 +1212,12 @@ class PAGMO_DLL_PUBLIC problem template T *extract() noexcept { - // auto p = dynamic_cast *>(ptr()); - // return p == nullptr ? nullptr : &(p->m_value); - if (get_type_index().name() == typeid(T).name()) { - return static_cast(ptr()->get_void_ptr()); - } else { - return nullptr; - } +#if defined(PAGMO_PREFER_TYPEID_NAME_EXTRACT) + return detail::typeid_name_extract(*this); +#else + auto p = dynamic_cast *>(ptr()); + return p == nullptr ? nullptr : &(p->m_value); +#endif } /// Check if the UDP used for construction is of type \p T. @@ -1622,6 +1623,50 @@ class PAGMO_DLL_PUBLIC problem // Get the type at runtime. std::type_index get_type_index() const; + /// Get a const pointer to the UDP. + /** + * \verbatim embed:rst:leading-asterisk + * .. versionadded:: 2.15 + * + * This function will return a raw const pointer + * to the internal UDP instance. Differently from + * :cpp:func:`~pagmo::problem::extract()`, this function + * does not require to pass the correct type + * in input. It is however the user's responsibility + * to cast the returned void pointer to the correct type. + * + * .. note:: + * + * The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime + * of ``this``, and ``delete`` must never be called on the pointer. + * \endverbatim + * + * @return a pointer to the internal UDP. + */ + const void *get_void_ptr() const; + + /// Get a mutable pointer to the UDP. + /** + * \verbatim embed:rst:leading-asterisk + * .. versionadded:: 2.15 + * + * This function will return a raw pointer + * to the internal UDP instance. Differently from + * :cpp:func:`~pagmo::problem::extract()`, this function + * does not require to pass the correct type + * in input. It is however the user's responsibility + * to cast the returned void pointer to the correct type. + * + * .. note:: + * + * The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime + * of ``this``, and ``delete`` must never be called on the pointer. + * \endverbatim + * + * @return a pointer to the internal UDP. + */ + void *get_void_ptr(); + /// Save to archive. /** * This method will save \p this into the archive \p ar. diff --git a/include/pagmo/problems/decompose.hpp b/include/pagmo/problems/decompose.hpp index 489031da1..25599573e 100644 --- a/include/pagmo/problems/decompose.hpp +++ b/include/pagmo/problems/decompose.hpp @@ -180,10 +180,29 @@ class PAGMO_DLL_PUBLIC decompose // Problem's thread safety level. thread_safety get_thread_safety() const; - // Getter for the inner problem. + /// Getter for the inner problem. + /** + * Returns a const reference to the inner pagmo::problem. + * + * @return a const reference to the inner pagmo::problem. + */ const problem &get_inner_problem() const; - // Getter for the inner problem. + /// Getter for the inner problem. + /** + * Returns a reference to the inner pagmo::problem. + * + * \verbatim embed:rst:leading-asterisk + * .. note:: + * + * The ability to extract a non const reference is provided only in order to allow to call + * non-const methods on the internal :cpp:class:`pagmo::problem` instance. Assigning a new + * :class:`pagmo::problem` via this reference is undefined behaviour. + * + * \endverbatim + * + * @return a reference to the inner pagmo::problem. + */ problem &get_inner_problem(); // Object serialization. diff --git a/include/pagmo/problems/translate.hpp b/include/pagmo/problems/translate.hpp index 5c0161515..49de72a3d 100644 --- a/include/pagmo/problems/translate.hpp +++ b/include/pagmo/problems/translate.hpp @@ -154,10 +154,29 @@ class PAGMO_DLL_PUBLIC translate // Problem's thread safety level. thread_safety get_thread_safety() const; - // Getter for the inner problem. + /// Getter for the inner problem. + /** + * Returns a const reference to the inner pagmo::problem. + * + * @return a const reference to the inner pagmo::problem. + */ const problem &get_inner_problem() const; - // Getter for the inner problem. + /// Getter for the inner problem. + /** + * Returns a reference to the inner pagmo::problem. + * + * \verbatim embed:rst:leading-asterisk + * .. note:: + * + * The ability to extract a non const reference is provided only in order to allow to call + * non-const methods on the internal :cpp:class:`pagmo::problem` instance. Assigning a new + * :cpp:class:`pagmo::problem` via this reference is undefined behaviour. + * + * \endverbatim + * + * @return a reference to the inner pagmo::problem. + */ problem &get_inner_problem(); // Object serialization diff --git a/include/pagmo/problems/unconstrain.hpp b/include/pagmo/problems/unconstrain.hpp index c376a3315..75e7d202e 100644 --- a/include/pagmo/problems/unconstrain.hpp +++ b/include/pagmo/problems/unconstrain.hpp @@ -127,10 +127,29 @@ class PAGMO_DLL_PUBLIC unconstrain // Problem's thread safety level. thread_safety get_thread_safety() const; - // Getter for the inner problem. + /// Getter for the inner problem. + /** + * Returns a const reference to the inner pagmo::problem. + * + * @return a const reference to the inner pagmo::problem. + */ const problem &get_inner_problem() const; - // Getter for the inner problem. + /// Getter for the inner problem. + /** + * Returns a reference to the inner pagmo::problem. + * + * \verbatim embed:rst:leading-asterisk + * .. note:: + * + * The ability to extract a non const reference is provided only in order to allow to call + * non-const methods on the internal :cpp:class:`pagmo::problem` instance. Assigning a new + * :cpp:class:`pagmo::problem` via this reference is undefined behaviour. + * + * \endverbatim + * + * @return a reference to the inner pagmo::problem. + */ problem &get_inner_problem(); // Problem name. diff --git a/include/pagmo/rng.hpp b/include/pagmo/rng.hpp index 7297a2e91..b612f3623 100644 --- a/include/pagmo/rng.hpp +++ b/include/pagmo/rng.hpp @@ -57,7 +57,15 @@ using random_engine_type = std::mt19937; */ struct PAGMO_DLL_PUBLIC random_device { static unsigned next(); - static void set_seed(unsigned); + /// Sets the seed for the PRS + /** + * This static method sets a new seed for the PRS, so that all the + * following calls to random_device::next() will always repeat the same + * numbers. + * + * @param seed The new seed to be used + */ + static void set_seed(unsigned seed); }; } // namespace pagmo diff --git a/src/problem.cpp b/src/problem.cpp index a8e57cc58..52b241cd8 100644 --- a/src/problem.cpp +++ b/src/problem.cpp @@ -743,12 +743,33 @@ bool problem::is_valid() const return static_cast(m_ptr); } -// Get the type at runtime. +/// Get the type of the UDP. +/** + * \verbatim embed:rst:leading-asterisk + * .. versionadded:: 2.15 + * + * This function will return the type + * of the UDP stored within this problem + * instance. + * \endverbatim + * + * @return the type of the UDP. + */ std::type_index problem::get_type_index() const { return ptr()->get_type_index(); } +const void *problem::get_void_ptr() const +{ + return ptr()->get_void_ptr(); +} + +void *problem::get_void_ptr() +{ + return ptr()->get_void_ptr(); +} + /// Streaming operator /** * This function will stream to \p os a human-readable representation of the input diff --git a/src/problems/decompose.cpp b/src/problems/decompose.cpp index de9d2b80e..72559fb78 100644 --- a/src/problems/decompose.cpp +++ b/src/problems/decompose.cpp @@ -275,32 +275,11 @@ thread_safety decompose::get_thread_safety() const return m_problem.get_thread_safety(); } -/// Getter for the inner problem. -/** - * Returns a const reference to the inner pagmo::problem. - * - * @return a const reference to the inner pagmo::problem. - */ const problem &decompose::get_inner_problem() const { return m_problem; } -/// Getter for the inner problem. -/** - * Returns a reference to the inner pagmo::problem. - * - * \verbatim embed:rst:leading-asterisk - * .. note:: - * - * The ability to extract a non const reference is provided only in order to allow to call - * non-const methods on the internal :cpp:class:`pagmo::problem` instance. Assigning a new - * :class:`pagmo::problem` via this reference is undefined behaviour. - * - * \endverbatim - * - * @return a reference to the inner pagmo::problem. - */ problem &decompose::get_inner_problem() { return m_problem; diff --git a/src/problems/translate.cpp b/src/problems/translate.cpp index 4abd72bc2..3b6e247cd 100644 --- a/src/problems/translate.cpp +++ b/src/problems/translate.cpp @@ -380,32 +380,11 @@ thread_safety translate::get_thread_safety() const return m_problem.get_thread_safety(); } -/// Getter for the inner problem. -/** - * Returns a const reference to the inner pagmo::problem. - * - * @return a const reference to the inner pagmo::problem. - */ const problem &translate::get_inner_problem() const { return m_problem; } -/// Getter for the inner problem. -/** - * Returns a reference to the inner pagmo::problem. - * - * \verbatim embed:rst:leading-asterisk - * .. note:: - * - * The ability to extract a non const reference is provided only in order to allow to call - * non-const methods on the internal :cpp:class:`pagmo::problem` instance. Assigning a new - * :cpp:class:`pagmo::problem` via this reference is undefined behaviour. - * - * \endverbatim - * - * @return a reference to the inner pagmo::problem. - */ problem &translate::get_inner_problem() { return m_problem; diff --git a/src/problems/unconstrain.cpp b/src/problems/unconstrain.cpp index ba4491155..ac31f8d72 100644 --- a/src/problems/unconstrain.cpp +++ b/src/problems/unconstrain.cpp @@ -269,32 +269,11 @@ thread_safety unconstrain::get_thread_safety() const return m_problem.get_thread_safety(); } -/// Getter for the inner problem. -/** - * Returns a const reference to the inner pagmo::problem. - * - * @return a const reference to the inner pagmo::problem. - */ const problem &unconstrain::get_inner_problem() const { return m_problem; } -/// Getter for the inner problem. -/** - * Returns a reference to the inner pagmo::problem. - * - * \verbatim embed:rst:leading-asterisk - * .. note:: - * - * The ability to extract a non const reference is provided only in order to allow to call - * non-const methods on the internal :cpp:class:`pagmo::problem` instance. Assigning a new - * :cpp:class:`pagmo::problem` via this reference is undefined behaviour. - * - * \endverbatim - * - * @return a reference to the inner pagmo::problem. - */ problem &unconstrain::get_inner_problem() { return m_problem; diff --git a/src/rng.cpp b/src/rng.cpp index 3e8d3cb24..d51f446f3 100644 --- a/src/rng.cpp +++ b/src/rng.cpp @@ -61,14 +61,6 @@ unsigned random_device::next() return static_cast(detail::global_rng()); } -/// Sets the seed for the PRS -/** - * This static method sets a new seed for the PRS, so that all the - * following calls to random_device::next() will always repeat the same - * numbers. - * - * @param seed The new seed to be used - */ void random_device::set_seed(unsigned seed) { std::lock_guard lock(detail::global_rng_mutex); From 231b42d4d102c04684aaea6120ecb0725a98e2da Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Fri, 27 Mar 2020 10:20:20 +0100 Subject: [PATCH 05/30] Testing additions. --- tests/problem.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/tests/problem.cpp b/tests/problem.cpp index a4d2bc26a..90e0a7455 100644 --- a/tests/problem.cpp +++ b/tests/problem.cpp @@ -36,6 +36,7 @@ see https://www.gnu.org/licenses/. */ #include #include #include +#include #include #include #include @@ -1599,7 +1600,19 @@ BOOST_AUTO_TEST_CASE(generic_assignment) BOOST_AUTO_TEST_CASE(type_index) { problem p0; - std::cout << p0 << '\n'; + BOOST_CHECK(p0.get_type_index() == std::type_index(typeid(null_problem))); p0 = problem{grad_p_override{}}; - std::cout << p0 << '\n'; + BOOST_CHECK(p0.get_type_index() == std::type_index(typeid(grad_p_override))); +} + +BOOST_AUTO_TEST_CASE(get_void_ptr) +{ + problem p0; + BOOST_CHECK(p0.get_void_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_void_ptr() + == static_cast(p0).extract()); + p0 = problem{grad_p_override{}}; + BOOST_CHECK(p0.get_void_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_void_ptr() + == static_cast(p0).extract()); } From d584b989331274aa3965cb028642ba3a2d93ba0a Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Fri, 27 Mar 2020 10:20:43 +0100 Subject: [PATCH 06/30] Squashed 'cmake_modules/yacma/' changes from 14b830d9..9b555308 9b555308 More YACMA bits. 8d4e2917 yacma fix for recent CMake versions. 4942670c Merge commit '9dd6fbba6dc9283ac77899901e6c026d0b016e23' into pr/dates a0fa858c Update copyright dates for 2020. 19ed5f95 Update yacma copyright date. git-subtree-dir: cmake_modules/yacma git-subtree-split: 9b5553088aba21f8deab536aae3551f09cce4e49 --- LICENSE | 2 +- YACMACompilerLinkerSettings.cmake | 37 ++++++++++++++++++++++--------- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/LICENSE b/LICENSE index 16577b9df..edd52cf34 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2016-2019 Francesco Biscani +Copyright (c) 2016-2020 Francesco Biscani Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/YACMACompilerLinkerSettings.cmake b/YACMACompilerLinkerSettings.cmake index d8c387594..7d7aa1bfc 100644 --- a/YACMACompilerLinkerSettings.cmake +++ b/YACMACompilerLinkerSettings.cmake @@ -44,36 +44,32 @@ endfunction() # Enable conditionally a CXX flag, if supported by the compiler. # This is for flags intended to be enabled in all configurations. -# NOTE: we use macros and go through temporary private variables -# because it's apparently impossible to append to an internal +# NOTE: we use macros because it's apparently impossible to append to an internal # CACHEd list. macro(_YACMA_CHECK_ENABLE_CXX_FLAG flag) set(CMAKE_REQUIRED_QUIET TRUE) - check_cxx_compiler_flag("${flag}" YACMA_CHECK_CXX_FLAG) + check_cxx_compiler_flag("${flag}" YACMA_CHECK_CXX_FLAG::${flag}) unset(CMAKE_REQUIRED_QUIET) - if(YACMA_CHECK_CXX_FLAG) + if(YACMA_CHECK_CXX_FLAG::${flag}) message(STATUS "'${flag}': flag is supported by the compiler, enabling.") list(APPEND _YACMA_CXX_FLAGS "${flag}") else() message(STATUS "'${flag}': flag is not supported by the compiler.") endif() - # NOTE: check_cxx_compiler stores variables in the cache. - unset(YACMA_CHECK_CXX_FLAG CACHE) endmacro() # Enable conditionally a debug CXX flag, is supported by the compiler. # This is for flags intended to be enabled in debug mode. macro(_YACMA_CHECK_ENABLE_DEBUG_CXX_FLAG flag) set(CMAKE_REQUIRED_QUIET TRUE) - check_cxx_compiler_flag("${flag}" YACMA_CHECK_DEBUG_CXX_FLAG) + check_cxx_compiler_flag("${flag}" YACMA_CHECK_DEBUG_CXX_FLAG::${flag}) unset(CMAKE_REQUIRED_QUIET) - if(YACMA_CHECK_DEBUG_CXX_FLAG) + if(YACMA_CHECK_DEBUG_CXX_FLAG::${flag}) message(STATUS "'${flag}': debug flag is supported by the compiler, enabling.") list(APPEND _YACMA_CXX_FLAGS_DEBUG "${flag}") else() message(STATUS "'${flag}': debug flag is not supported by the compiler.") endif() - unset(YACMA_CHECK_DEBUG_CXX_FLAG CACHE) endmacro() # What we want to avoid is to re-run the expensive flag checks. We will set cache variables @@ -86,6 +82,8 @@ if(NOT _YACMACompilerLinkerSettingsRun) # Configuration bits specific for GCC. if(YACMA_COMPILER_IS_GNUCXX) _YACMA_CHECK_ENABLE_CXX_FLAG(-fdiagnostics-color=auto) + # New in GCC 9. + _YACMA_CHECK_ENABLE_DEBUG_CXX_FLAG(-Waddress-of-packed-member) endif() # Configuration bits specific for clang. @@ -94,7 +92,26 @@ if(NOT _YACMACompilerLinkerSettingsRun) # for the time being. _YACMA_CHECK_ENABLE_DEBUG_CXX_FLAG(-Wshadow) # Clang is better at this flag than GCC. - _YACMA_CHECK_ENABLE_DEBUG_CXX_FLAG(-Werror) + # NOTE: enable unconditionally, as it seems like the CMake + # machinery for detecting this fails. Perhaps the source code + # used for checking the flag emits warnings? + list(APPEND _YACMA_CXX_FLAGS_DEBUG "-Werror") + # New warnings in clang 8. + # NOTE: a few issues with macros here, let's disable for now. + # _YACMA_CHECK_ENABLE_DEBUG_CXX_FLAG(-Wextra-semi-stmt) + # New warnings in clang 10. + _YACMA_CHECK_ENABLE_DEBUG_CXX_FLAG(-Wtautological-overlap-compare) + _YACMA_CHECK_ENABLE_DEBUG_CXX_FLAG(-Wtautological-compare) + _YACMA_CHECK_ENABLE_DEBUG_CXX_FLAG(-Wtautological-bitwise-compare) + _YACMA_CHECK_ENABLE_DEBUG_CXX_FLAG(-Wbitwise-conditional-parentheses) + _YACMA_CHECK_ENABLE_DEBUG_CXX_FLAG(-Wrange-loop-analysis) + _YACMA_CHECK_ENABLE_DEBUG_CXX_FLAG(-Wmisleading-indentation) + _YACMA_CHECK_ENABLE_DEBUG_CXX_FLAG(-Wc99-designator) + _YACMA_CHECK_ENABLE_DEBUG_CXX_FLAG(-Wreorder-init-list) + _YACMA_CHECK_ENABLE_DEBUG_CXX_FLAG(-Wsizeof-pointer-div) + _YACMA_CHECK_ENABLE_DEBUG_CXX_FLAG(-Wsizeof-array-div) + _YACMA_CHECK_ENABLE_DEBUG_CXX_FLAG(-Wxor-used-as-pow) + _YACMA_CHECK_ENABLE_DEBUG_CXX_FLAG(-Wfinal-dtor-non-final-class) endif() # Common configuration for GCC, clang and Intel. From 72ff04d36ce930fceaeb062a3366dba875a06a87 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Fri, 27 Mar 2020 10:39:27 +0100 Subject: [PATCH 07/30] Try pinning doxygen. --- tools/circleci_bionic_gcc7_conda_docs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/circleci_bionic_gcc7_conda_docs.sh b/tools/circleci_bionic_gcc7_conda_docs.sh index c475f4735..58a9c84e1 100644 --- a/tools/circleci_bionic_gcc7_conda_docs.sh +++ b/tools/circleci_bionic_gcc7_conda_docs.sh @@ -15,7 +15,7 @@ export deps_dir=$HOME/local export PATH="$HOME/miniconda/bin:$PATH" bash miniconda.sh -b -p $HOME/miniconda conda config --add channels conda-forge --force -conda_pkgs="cmake eigen nlopt ipopt boost-cpp tbb tbb-devel python=3.7 sphinx sphinx_rtd_theme breathe doxygen graphviz" +conda_pkgs="cmake eigen nlopt ipopt boost-cpp tbb tbb-devel python=3.7 sphinx sphinx_rtd_theme breathe doxygen=1.8.16 graphviz" conda create -q -p $deps_dir -y source activate $deps_dir conda install $conda_pkgs -y From 1fd8426015dccecf5d462905fe10b6a3bf39ce5a Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 28 Mar 2020 15:05:49 +0100 Subject: [PATCH 08/30] Unpin. --- tools/circleci_bionic_gcc7_conda_docs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/circleci_bionic_gcc7_conda_docs.sh b/tools/circleci_bionic_gcc7_conda_docs.sh index 58a9c84e1..c475f4735 100644 --- a/tools/circleci_bionic_gcc7_conda_docs.sh +++ b/tools/circleci_bionic_gcc7_conda_docs.sh @@ -15,7 +15,7 @@ export deps_dir=$HOME/local export PATH="$HOME/miniconda/bin:$PATH" bash miniconda.sh -b -p $HOME/miniconda conda config --add channels conda-forge --force -conda_pkgs="cmake eigen nlopt ipopt boost-cpp tbb tbb-devel python=3.7 sphinx sphinx_rtd_theme breathe doxygen=1.8.16 graphviz" +conda_pkgs="cmake eigen nlopt ipopt boost-cpp tbb tbb-devel python=3.7 sphinx sphinx_rtd_theme breathe doxygen graphviz" conda create -q -p $deps_dir -y source activate $deps_dir conda install $conda_pkgs -y From a0e9b1d9734ac6b509aca32d2c020e471e2f6379 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 28 Mar 2020 15:06:50 +0100 Subject: [PATCH 09/30] Fix NSPSO docs. --- doc/sphinx/overview.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/sphinx/overview.rst b/doc/sphinx/overview.rst index 7cdcd2f12..ac0f53f7f 100644 --- a/doc/sphinx/overview.rst +++ b/doc/sphinx/overview.rst @@ -86,7 +86,7 @@ Exponential Evolution Strategies (xNES) :cpp:class:`pagmo::xn Non-dominated Sorting GA (NSGA2) :cpp:class:`pagmo::nsga2` M-U-I Multi-objective EA vith Decomposition (MOEA/D) :cpp:class:`pagmo::moead` M-U Multi-objective Hypervolume-based ACO (MHACO) :cpp:class:`pagmo::maco` M-U-I -Non-dominated Sorting PSO (NSPSO) :cpp:class:`pagmo::nspso` M-U-I +Non-dominated Sorting PSO (NSPSO) :cpp:class:`pagmo::nspso` M-U ========================================================== ========================================= ========================= Local optimization From 1089b6f2102de7e564583e1ea6b561528fe5f0b1 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 28 Mar 2020 15:19:00 +0100 Subject: [PATCH 10/30] Add runtime type info to pagmo::algorithm. --- include/pagmo/algorithm.hpp | 79 ++++++++++++++++++++++++++++++++++++- src/algorithm.cpp | 30 ++++++++++++++ tests/algorithm.cpp | 25 +++++++++++- 3 files changed, 131 insertions(+), 3 deletions(-) diff --git a/include/pagmo/algorithm.hpp b/include/pagmo/algorithm.hpp index e86217f90..4b127ff71 100644 --- a/include/pagmo/algorithm.hpp +++ b/include/pagmo/algorithm.hpp @@ -33,14 +33,18 @@ see https://www.gnu.org/licenses/. */ #include #include #include +#include #include #include #include #include +#include #include #include +#include +#include #include #include #include @@ -186,6 +190,9 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS algo_inner_base { virtual std::string get_name() const = 0; virtual std::string get_extra_info() const = 0; virtual thread_safety get_thread_safety() const = 0; + virtual std::type_index get_type_index() const = 0; + virtual const void *get_void_ptr() const = 0; + virtual void *get_void_ptr() = 0; template void serialize(Archive &, unsigned) { @@ -311,7 +318,7 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS algo_inner final : algo_inner_base { template ::value, int> = 0> static std::string get_name_impl(const U &) { - return typeid(U).name(); + return detail::type_name(); } template ::value, int> = 0> static std::string get_extra_info_impl(const U &value) @@ -333,7 +340,20 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS algo_inner final : algo_inner_base { { return thread_safety::basic; } - + // Get the type at runtime. + virtual std::type_index get_type_index() const override final + { + return std::type_index(typeid(T)); + } + // Raw getters for the internal instance. + virtual const void *get_void_ptr() const override final + { + return &m_value; + } + virtual void *get_void_ptr() override final + { + return &m_value; + } // Serialization template void serialize(Archive &ar, unsigned) @@ -505,8 +525,12 @@ class PAGMO_DLL_PUBLIC algorithm template const T *extract() const noexcept { +#if defined(PAGMO_PREFER_TYPEID_NAME_EXTRACT) + return detail::typeid_name_extract(*this); +#else auto p = dynamic_cast *>(ptr()); return p == nullptr ? nullptr : &(p->m_value); +#endif } /// Extract a pointer to the UDA. @@ -538,8 +562,12 @@ class PAGMO_DLL_PUBLIC algorithm template T *extract() noexcept { +#if defined(PAGMO_PREFER_TYPEID_NAME_EXTRACT) + return detail::typeid_name_extract(*this); +#else auto p = dynamic_cast *>(ptr()); return p == nullptr ? nullptr : &(p->m_value); +#endif } /// Checks the user-defined algorithm type at run-time. @@ -640,6 +668,53 @@ class PAGMO_DLL_PUBLIC algorithm // Check if the algorithm is valid. bool is_valid() const; + // Get the type at runtime. + std::type_index get_type_index() const; + + /// Get a const pointer to the UDA. + /** + * \verbatim embed:rst:leading-asterisk + * .. versionadded:: 2.15 + * + * This function will return a raw const pointer + * to the internal UDA instance. Differently from + * :cpp:func:`~pagmo::algorithm::extract()`, this function + * does not require to pass the correct type + * in input. It is however the user's responsibility + * to cast the returned void pointer to the correct type. + * + * .. note:: + * + * The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime + * of ``this``, and ``delete`` must never be called on the pointer. + * \endverbatim + * + * @return a pointer to the internal UDA. + */ + const void *get_void_ptr() const; + + /// Get a mutable pointer to the UDA. + /** + * \verbatim embed:rst:leading-asterisk + * .. versionadded:: 2.15 + * + * This function will return a raw pointer + * to the internal UDA instance. Differently from + * :cpp:func:`~pagmo::algorithm::extract()`, this function + * does not require to pass the correct type + * in input. It is however the user's responsibility + * to cast the returned void pointer to the correct type. + * + * .. note:: + * + * The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime + * of ``this``, and ``delete`` must never be called on the pointer. + * \endverbatim + * + * @return a pointer to the internal UDA. + */ + void *get_void_ptr(); + /// Save to archive. /** * This method will save \p this into the archive \p ar. diff --git a/src/algorithm.cpp b/src/algorithm.cpp index 76e394e77..0b55018f9 100644 --- a/src/algorithm.cpp +++ b/src/algorithm.cpp @@ -28,10 +28,12 @@ see https://www.gnu.org/licenses/. */ #include #include +#include #include #include #include +#include #include #include @@ -197,6 +199,33 @@ bool algorithm::is_valid() const return static_cast(m_ptr); } +/// Get the type of the UDA. +/** + * \verbatim embed:rst:leading-asterisk + * .. versionadded:: 2.15 + * + * This function will return the type + * of the UDA stored within this algorithm + * instance. + * \endverbatim + * + * @return the type of the UDA. + */ +std::type_index algorithm::get_type_index() const +{ + return ptr()->get_type_index(); +} + +const void *algorithm::get_void_ptr() const +{ + return ptr()->get_void_ptr(); +} + +void *algorithm::get_void_ptr() +{ + return ptr()->get_void_ptr(); +} + /// Streaming operator for pagmo::algorithm /** * This function will stream to \p os a human-readable representation of the input @@ -217,6 +246,7 @@ std::ostream &operator<<(std::ostream &os, const algorithm &a) } else { stream(os, " [stochastic]"); } + os << "\n\tC++ class name: " << detail::demangle_from_typeid(a.get_type_index().name()) << '\n'; stream(os, "\n\tThread safety: ", a.get_thread_safety(), '\n'); const auto extra_str = a.get_extra_info(); if (!extra_str.empty()) { diff --git a/tests/algorithm.cpp b/tests/algorithm.cpp index 4aeeeb367..474a734e9 100644 --- a/tests/algorithm.cpp +++ b/tests/algorithm.cpp @@ -34,6 +34,8 @@ see https://www.gnu.org/licenses/. */ #include #include #include +#include +#include #include #include @@ -42,6 +44,7 @@ see https://www.gnu.org/licenses/. */ #include #include #include +#include #include #include #include @@ -117,7 +120,7 @@ BOOST_AUTO_TEST_CASE(algorithm_construction_test) BOOST_CHECK_THROW(algo_minimal.set_verbosity(1u), not_implemented_error); // We check that at construction the name has been assigned BOOST_CHECK(algo_full.get_name() == "name"); - BOOST_CHECK(algo_minimal.get_name().find("al_02") != std::string::npos); + BOOST_CHECK(algo_minimal.get_name() == detail::type_name()); // Default constructor. algorithm a0; BOOST_CHECK((a0.extract() != nullptr)); @@ -497,3 +500,23 @@ BOOST_AUTO_TEST_CASE(generic_assignment) BOOST_CHECK((!std::is_assignable::value)); BOOST_CHECK((!std::is_assignable::value)); } + +BOOST_AUTO_TEST_CASE(type_index) +{ + algorithm p0; + BOOST_CHECK(p0.get_type_index() == std::type_index(typeid(null_algorithm))); + p0 = algorithm{al_01{}}; + BOOST_CHECK(p0.get_type_index() == std::type_index(typeid(al_01))); +} + +BOOST_AUTO_TEST_CASE(get_void_ptr) +{ + algorithm p0; + BOOST_CHECK(p0.get_void_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_void_ptr() + == static_cast(p0).extract()); + p0 = algorithm{al_01{}}; + BOOST_CHECK(p0.get_void_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_void_ptr() + == static_cast(p0).extract()); +} From 12058c554d7b7dd95677b9144e0b290f02700ebb Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 28 Mar 2020 15:36:28 +0100 Subject: [PATCH 11/30] Ditto for UDI. --- include/pagmo/island.hpp | 79 +++++++++++++++++++++++++++++++++++++++- src/island.cpp | 30 +++++++++++++++ tests/algorithm.cpp | 6 +++ tests/island.cpp | 27 ++++++++++++++ 4 files changed, 141 insertions(+), 1 deletion(-) diff --git a/include/pagmo/island.hpp b/include/pagmo/island.hpp index 75b8d2720..113d0f338 100644 --- a/include/pagmo/island.hpp +++ b/include/pagmo/island.hpp @@ -38,6 +38,7 @@ see https://www.gnu.org/licenses/. */ #include #include #include +#include #include #include #include @@ -48,11 +49,14 @@ see https://www.gnu.org/licenses/. */ #include #include +#include #include #include #include #include #include +#include +#include #include #include #include @@ -147,6 +151,9 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS isl_inner_base { virtual void run_evolve(island &) const = 0; virtual std::string get_name() const = 0; virtual std::string get_extra_info() const = 0; + virtual std::type_index get_type_index() const = 0; + virtual const void *get_void_ptr() const = 0; + virtual void *get_void_ptr() = 0; template void serialize(Archive &, unsigned) { @@ -191,7 +198,7 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS isl_inner final : isl_inner_base { template ::value, int> = 0> static std::string get_name_impl(const U &) { - return typeid(U).name(); + return detail::type_name(); } template ::value, int> = 0> static std::string get_extra_info_impl(const U &value) @@ -203,6 +210,20 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS isl_inner final : isl_inner_base { { return ""; } + // Get the type at runtime. + virtual std::type_index get_type_index() const override final + { + return std::type_index(typeid(T)); + } + // Raw getters for the internal instance. + virtual const void *get_void_ptr() const override final + { + return &m_value; + } + virtual void *get_void_ptr() override final + { + return &m_value; + } // Serialization template void serialize(Archive &ar, unsigned) @@ -992,8 +1013,12 @@ class PAGMO_DLL_PUBLIC island template const T *extract() const noexcept { +#if defined(PAGMO_PREFER_TYPEID_NAME_EXTRACT) + return detail::typeid_name_extract(*this); +#else auto isl = dynamic_cast *>(m_ptr->isl_ptr.get()); return isl == nullptr ? nullptr : &(isl->m_value); +#endif } /// Extract a pointer to the UDI used for construction. /** @@ -1021,8 +1046,12 @@ class PAGMO_DLL_PUBLIC island template T *extract() noexcept { +#if defined(PAGMO_PREFER_TYPEID_NAME_EXTRACT) + return detail::typeid_name_extract(*this); +#else auto isl = dynamic_cast *>(m_ptr->isl_ptr.get()); return isl == nullptr ? nullptr : &(isl->m_value); +#endif } /// Check if the UDI used for construction is of type \p T. /** @@ -1105,6 +1134,54 @@ class PAGMO_DLL_PUBLIC island // Check if the island is valid. bool is_valid() const; + + // Get the type at runtime. + std::type_index get_type_index() const; + + /// Get a const pointer to the UDI. + /** + * \verbatim embed:rst:leading-asterisk + * .. versionadded:: 2.15 + * + * This function will return a raw const pointer + * to the internal UDI instance. Differently from + * :cpp:func:`~pagmo::island::extract()`, this function + * does not require to pass the correct type + * in input. It is however the user's responsibility + * to cast the returned void pointer to the correct type. + * + * .. note:: + * + * The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime + * of ``this``, and ``delete`` must never be called on the pointer. + * \endverbatim + * + * @return a pointer to the internal UDI. + */ + const void *get_void_ptr() const; + + /// Get a mutable pointer to the UDI. + /** + * \verbatim embed:rst:leading-asterisk + * .. versionadded:: 2.15 + * + * This function will return a raw pointer + * to the internal UDI instance. Differently from + * :cpp:func:`~pagmo::island::extract()`, this function + * does not require to pass the correct type + * in input. It is however the user's responsibility + * to cast the returned void pointer to the correct type. + * + * .. note:: + * + * The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime + * of ``this``, and ``delete`` must never be called on the pointer. + * \endverbatim + * + * @return a pointer to the internal UDI. + */ + void *get_void_ptr(); + /// Save to archive. /** * This method will save \p this to the archive \p ar. diff --git a/src/island.cpp b/src/island.cpp index 063edb8fe..9ab84ffe8 100644 --- a/src/island.cpp +++ b/src/island.cpp @@ -42,6 +42,7 @@ see https://www.gnu.org/licenses/. */ #include #include #include +#include #include #include #include @@ -53,6 +54,7 @@ see https://www.gnu.org/licenses/. */ #include #include #include +#include #include #include #include @@ -863,12 +865,40 @@ std::string island::get_extra_info() const return m_ptr->isl_ptr->get_extra_info(); } +/// Get the type of the UDI. +/** + * \verbatim embed:rst:leading-asterisk + * .. versionadded:: 2.15 + * + * This function will return the type + * of the UDI stored within this island + * instance. + * \endverbatim + * + * @return the type of the UDI. + */ +std::type_index island::get_type_index() const +{ + return m_ptr->isl_ptr->get_type_index(); +} + +const void *island::get_void_ptr() const +{ + return m_ptr->isl_ptr->get_void_ptr(); +} + +void *island::get_void_ptr() +{ + return m_ptr->isl_ptr->get_void_ptr(); +} + #if !defined(PAGMO_DOXYGEN_INVOKED) // Stream operator for pagmo::island. std::ostream &operator<<(std::ostream &os, const island &isl) { stream(os, "Island name: ", isl.get_name()); + os << "\n\tC++ class name: " << detail::demangle_from_typeid(isl.get_type_index().name()) << '\n'; stream(os, "\n\tStatus: ", isl.status(), "\n\n"); const auto extra_str = isl.get_extra_info(); if (!extra_str.empty()) { diff --git a/tests/algorithm.cpp b/tests/algorithm.cpp index 474a734e9..fa43107f7 100644 --- a/tests/algorithm.cpp +++ b/tests/algorithm.cpp @@ -30,6 +30,7 @@ see https://www.gnu.org/licenses/. */ #define BOOST_TEST_DYN_LINK #include +#include #include #include #include @@ -520,3 +521,8 @@ BOOST_AUTO_TEST_CASE(get_void_ptr) BOOST_CHECK(static_cast(p0).get_void_ptr() == static_cast(p0).extract()); } + +BOOST_AUTO_TEST_CASE(stream_operator) +{ + std::cout << algorithm{} << '\n'; +} diff --git a/tests/island.cpp b/tests/island.cpp index c352dca83..d1d63cda9 100644 --- a/tests/island.cpp +++ b/tests/island.cpp @@ -38,6 +38,8 @@ see https://www.gnu.org/licenses/. */ #include #include #include +#include +#include #include #include @@ -49,6 +51,7 @@ see https://www.gnu.org/licenses/. */ #include #include #include +#include #include #include #include @@ -80,6 +83,10 @@ struct udi_01 { } }; +struct udi_01a { + void run_evolve(island &) const {} +}; + struct udi_02 { void run_evolve(island &); }; @@ -391,6 +398,7 @@ BOOST_AUTO_TEST_CASE(island_name_info_stream) oss << isl; BOOST_CHECK(!oss.str().empty()); BOOST_CHECK(isl.get_name() == "udi_01"); + BOOST_CHECK((island{udi_01a{}, de{}, population{rosenbrock{}, 25}}.get_name()) == detail::type_name()); BOOST_CHECK(isl.get_extra_info() == "extra bits"); BOOST_CHECK(boost::contains(oss.str(), "Replacement policy: Fair replace")); BOOST_CHECK(boost::contains(oss.str(), "Selection policy: Select best")); @@ -631,3 +639,22 @@ BOOST_AUTO_TEST_CASE(is_valid) p0 = island{udi_01{}, de{}, population{rosenbrock{}, 25}}; BOOST_CHECK(p0.is_valid()); } + +BOOST_AUTO_TEST_CASE(type_index) +{ + island p0; + BOOST_CHECK(p0.get_type_index() == std::type_index(typeid(thread_island))); + p0 = island{udi_01a{}, de{}, population{rosenbrock{}, 25}}; + BOOST_CHECK(p0.get_type_index() == std::type_index(typeid(udi_01a))); +} + +BOOST_AUTO_TEST_CASE(get_void_ptr) +{ + island p0; + BOOST_CHECK(p0.get_void_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_void_ptr() + == static_cast(p0).extract()); + p0 = island{udi_01a{}, de{}, population{rosenbrock{}, 25}}; + BOOST_CHECK(p0.get_void_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_void_ptr() == static_cast(p0).extract()); +} From 4bd0742123e0074168d398534290c76c995321d5 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 28 Mar 2020 15:55:36 +0100 Subject: [PATCH 12/30] Ditto for bfe. --- include/pagmo/bfe.hpp | 78 ++++++++++++++++++- include/pagmo/rng.hpp | 12 +-- include/pagmo/utils/hv_algos/hv_algorithm.hpp | 2 + src/bfe.cpp | 32 +++++++- src/rng.cpp | 12 +++ tests/bfe.cpp | 24 ++++++ 6 files changed, 150 insertions(+), 10 deletions(-) diff --git a/include/pagmo/bfe.hpp b/include/pagmo/bfe.hpp index 9b63cca44..d601498dc 100644 --- a/include/pagmo/bfe.hpp +++ b/include/pagmo/bfe.hpp @@ -34,14 +34,18 @@ see https://www.gnu.org/licenses/. */ #include #include #include +#include #include #include #include #include +#include #include #include +#include +#include #include #include #include @@ -118,6 +122,9 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS bfe_inner_base { virtual std::string get_name() const = 0; virtual std::string get_extra_info() const = 0; virtual thread_safety get_thread_safety() const = 0; + virtual std::type_index get_type_index() const = 0; + virtual const void *get_void_ptr() const = 0; + virtual void *get_void_ptr() = 0; template void serialize(Archive &, unsigned) { @@ -167,7 +174,7 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS bfe_inner final : bfe_inner_base { template ::value, int> = 0> static std::string get_name_impl(const U &) { - return typeid(U).name(); + return detail::type_name(); } template ::value, int> = 0> static std::string get_extra_info_impl(const U &value) @@ -189,6 +196,20 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS bfe_inner final : bfe_inner_base { { return thread_safety::basic; } + // Get the type at runtime. + virtual std::type_index get_type_index() const override final + { + return std::type_index(typeid(T)); + } + // Raw getters for the internal instance. + virtual const void *get_void_ptr() const override final + { + return &m_value; + } + virtual void *get_void_ptr() override final + { + return &m_value; + } // Serialization. template void serialize(Archive &ar, unsigned) @@ -272,14 +293,22 @@ class PAGMO_DLL_PUBLIC bfe template const T *extract() const noexcept { +#if defined(PAGMO_PREFER_TYPEID_NAME_EXTRACT) + return detail::typeid_name_extract(*this); +#else auto p = dynamic_cast *>(ptr()); return p == nullptr ? nullptr : &(p->m_value); +#endif } template T *extract() noexcept { +#if defined(PAGMO_PREFER_TYPEID_NAME_EXTRACT) + return detail::typeid_name_extract(*this); +#else auto p = dynamic_cast *>(ptr()); return p == nullptr ? nullptr : &(p->m_value); +#endif } template bool is() const noexcept @@ -307,6 +336,53 @@ class PAGMO_DLL_PUBLIC bfe // Check if the bfe is valid. bool is_valid() const; + // Get the type at runtime. + std::type_index get_type_index() const; + + /// Get a const pointer to the UDBFE. + /** + * \verbatim embed:rst:leading-asterisk + * .. versionadded:: 2.15 + * + * This function will return a raw const pointer + * to the internal UDBFE instance. Differently from + * :cpp:func:`~pagmo::bfe::extract()`, this function + * does not require to pass the correct type + * in input. It is however the user's responsibility + * to cast the returned void pointer to the correct type. + * + * .. note:: + * + * The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime + * of ``this``, and ``delete`` must never be called on the pointer. + * \endverbatim + * + * @return a pointer to the internal UDBFE. + */ + const void *get_void_ptr() const; + + /// Get a mutable pointer to the UDBFE. + /** + * \verbatim embed:rst:leading-asterisk + * .. versionadded:: 2.15 + * + * This function will return a raw pointer + * to the internal UDBFE instance. Differently from + * :cpp:func:`~pagmo::bfe::extract()`, this function + * does not require to pass the correct type + * in input. It is however the user's responsibility + * to cast the returned void pointer to the correct type. + * + * .. note:: + * + * The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime + * of ``this``, and ``delete`` must never be called on the pointer. + * \endverbatim + * + * @return a pointer to the internal UDBFE. + */ + void *get_void_ptr(); + // Serialisation support. template void save(Archive &ar, unsigned) const diff --git a/include/pagmo/rng.hpp b/include/pagmo/rng.hpp index b612f3623..01794e6bb 100644 --- a/include/pagmo/rng.hpp +++ b/include/pagmo/rng.hpp @@ -57,15 +57,11 @@ using random_engine_type = std::mt19937; */ struct PAGMO_DLL_PUBLIC random_device { static unsigned next(); - /// Sets the seed for the PRS - /** - * This static method sets a new seed for the PRS, so that all the - * following calls to random_device::next() will always repeat the same - * numbers. - * - * @param seed The new seed to be used - */ + +#if !defined(PAGMO_DOXYGEN_INVOKED) + // Sets the seed for the PRS. static void set_seed(unsigned seed); +#endif }; } // namespace pagmo diff --git a/include/pagmo/utils/hv_algos/hv_algorithm.hpp b/include/pagmo/utils/hv_algos/hv_algorithm.hpp index c13ef1bbb..541b40493 100644 --- a/include/pagmo/utils/hv_algos/hv_algorithm.hpp +++ b/include/pagmo/utils/hv_algos/hv_algorithm.hpp @@ -147,6 +147,7 @@ class PAGMO_DLL_PUBLIC hv_algorithm // Contributions method virtual std::vector contributions(std::vector &, const vector_double &) const; +#if !defined(PAGMO_DOXYGEN_INVOKED) /// Verification of input /** * This method serves as a verification method. @@ -157,6 +158,7 @@ class PAGMO_DLL_PUBLIC hv_algorithm */ virtual void verify_before_compute(const std::vector &points, const vector_double &r_point) const = 0; +#endif /// Clone method. /** diff --git a/src/bfe.cpp b/src/bfe.cpp index d3cf56f02..d5c096b54 100644 --- a/src/bfe.cpp +++ b/src/bfe.cpp @@ -28,6 +28,7 @@ see https://www.gnu.org/licenses/. */ #include #include +#include #include #include @@ -35,6 +36,7 @@ see https://www.gnu.org/licenses/. */ #include #include #include +#include #include #include @@ -119,12 +121,40 @@ bool bfe::is_valid() const return static_cast(m_ptr); } +/// Get the type of the UDBFE. +/** + * \verbatim embed:rst:leading-asterisk + * .. versionadded:: 2.15 + * + * This function will return the type + * of the UDBFE stored within this bfe + * instance. + * \endverbatim + * + * @return the type of the UDBFE. + */ +std::type_index bfe::get_type_index() const +{ + return ptr()->get_type_index(); +} + +const void *bfe::get_void_ptr() const +{ + return ptr()->get_void_ptr(); +} + +void *bfe::get_void_ptr() +{ + return ptr()->get_void_ptr(); +} + #if !defined(PAGMO_DOXYGEN_INVOKED) // Stream operator. std::ostream &operator<<(std::ostream &os, const bfe &b) { - os << "BFE name: " << b.get_name() << '\n'; + os << "BFE name: " << b.get_name(); + os << "\n\tC++ class name: " << detail::demangle_from_typeid(b.get_type_index().name()) << '\n'; os << "\n\tThread safety: " << b.get_thread_safety() << '\n'; const auto extra_str = b.get_extra_info(); if (!extra_str.empty()) { diff --git a/src/rng.cpp b/src/rng.cpp index d51f446f3..bd463ad69 100644 --- a/src/rng.cpp +++ b/src/rng.cpp @@ -61,10 +61,22 @@ unsigned random_device::next() return static_cast(detail::global_rng()); } +#if !defined(PAGMO_DOXYGEN_INVOKED) + +/// Sets the seed for the PRS +/** + * This static method sets a new seed for the PRS, so that all the + * following calls to random_device::next() will always repeat the same + * numbers. + * + * @param seed The new seed to be used + */ void random_device::set_seed(unsigned seed) { std::lock_guard lock(detail::global_rng_mutex); detail::global_rng.seed(static_cast(seed)); } +#endif + } // namespace pagmo diff --git a/tests/bfe.cpp b/tests/bfe.cpp index 1a36f9628..7a08808ee 100644 --- a/tests/bfe.cpp +++ b/tests/bfe.cpp @@ -38,11 +38,14 @@ see https://www.gnu.org/licenses/. */ #include #include +#include #include #include #include #include #include +#include +#include #include #include @@ -50,6 +53,7 @@ see https://www.gnu.org/licenses/. */ #include #include +#include #include #include #include @@ -152,6 +156,7 @@ BOOST_AUTO_TEST_CASE(basic_tests) BOOST_CHECK(bfe0.is()); BOOST_CHECK(!bfe0.is()); BOOST_CHECK(bfe0.get_name() == "Default batch fitness evaluator"); + BOOST_CHECK(bfe{udbfe1{}}.get_name() == detail::type_name()); BOOST_CHECK(bfe0.get_extra_info().empty()); BOOST_CHECK(bfe0.get_thread_safety() == thread_safety::basic); @@ -340,6 +345,7 @@ BOOST_AUTO_TEST_CASE(stream_operator) BOOST_CHECK(boost::contains(st, "bartoppo")); BOOST_CHECK(boost::contains(st, "Extra info:")); } + std::cout << bfe{} << '\n'; } BOOST_AUTO_TEST_CASE(call_operator) @@ -506,3 +512,21 @@ BOOST_AUTO_TEST_CASE(generic_assignment) BOOST_CHECK((!std::is_assignable::value)); BOOST_CHECK((!std::is_assignable::value)); } + +BOOST_AUTO_TEST_CASE(type_index) +{ + bfe p0; + BOOST_CHECK(p0.get_type_index() == std::type_index(typeid(default_bfe))); + p0 = bfe{udbfe1{}}; + BOOST_CHECK(p0.get_type_index() == std::type_index(typeid(udbfe1))); +} + +BOOST_AUTO_TEST_CASE(get_void_ptr) +{ + bfe p0; + BOOST_CHECK(p0.get_void_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_void_ptr() == static_cast(p0).extract()); + p0 = bfe{udbfe1{}}; + BOOST_CHECK(p0.get_void_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_void_ptr() == static_cast(p0).extract()); +} From e1353de6a18725b4916552254d0c30f10518e5f3 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 28 Mar 2020 16:07:26 +0100 Subject: [PATCH 13/30] Ditto for topology. --- include/pagmo/topology.hpp | 78 +++++++++++++++++++++++++++++++++++++- src/topology.cpp | 30 +++++++++++++++ tests/topology.cpp | 35 +++++++++++++++++ 3 files changed, 142 insertions(+), 1 deletion(-) diff --git a/include/pagmo/topology.hpp b/include/pagmo/topology.hpp index 9eb74d0e3..d76acdefc 100644 --- a/include/pagmo/topology.hpp +++ b/include/pagmo/topology.hpp @@ -35,6 +35,7 @@ see https://www.gnu.org/licenses/. */ #include #include #include +#include #include #include #include @@ -43,8 +44,11 @@ see https://www.gnu.org/licenses/. */ #include #include +#include #include #include +#include +#include #include #include #include @@ -171,6 +175,9 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS topo_inner_base { virtual std::pair, vector_double> get_connections(std::size_t) const = 0; virtual void push_back() = 0; virtual bgl_graph_t to_bgl() const = 0; + virtual std::type_index get_type_index() const = 0; + virtual const void *get_void_ptr() const = 0; + virtual void *get_void_ptr() = 0; template void serialize(Archive &, unsigned) { @@ -236,7 +243,7 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS topo_inner final : topo_inner_base { template ::value, int> = 0> static std::string get_name_impl(const U &) { - return typeid(U).name(); + return detail::type_name(); } template ::value, int> = 0> static std::string get_extra_info_impl(const U &value) @@ -248,6 +255,20 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS topo_inner final : topo_inner_base { { return ""; } + // Get the type at runtime. + virtual std::type_index get_type_index() const override final + { + return std::type_index(typeid(T)); + } + // Raw getters for the internal instance. + virtual const void *get_void_ptr() const override final + { + return &m_value; + } + virtual void *get_void_ptr() override final + { + return &m_value; + } // Serialization template void serialize(Archive &ar, unsigned) @@ -315,14 +336,22 @@ class PAGMO_DLL_PUBLIC topology template const T *extract() const noexcept { +#if defined(PAGMO_PREFER_TYPEID_NAME_EXTRACT) + return detail::typeid_name_extract(*this); +#else auto p = dynamic_cast *>(ptr()); return p == nullptr ? nullptr : &(p->m_value); +#endif } template T *extract() noexcept { +#if defined(PAGMO_PREFER_TYPEID_NAME_EXTRACT) + return detail::typeid_name_extract(*this); +#else auto p = dynamic_cast *>(ptr()); return p == nullptr ? nullptr : &(p->m_value); +#endif } template bool is() const noexcept @@ -353,6 +382,53 @@ class PAGMO_DLL_PUBLIC topology // Convert to BGL. bgl_graph_t to_bgl() const; + // Get the type at runtime. + std::type_index get_type_index() const; + + /// Get a const pointer to the UDT. + /** + * \verbatim embed:rst:leading-asterisk + * .. versionadded:: 2.15 + * + * This function will return a raw const pointer + * to the internal UDT instance. Differently from + * :cpp:func:`~pagmo::topology::extract()`, this function + * does not require to pass the correct type + * in input. It is however the user's responsibility + * to cast the returned void pointer to the correct type. + * + * .. note:: + * + * The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime + * of ``this``, and ``delete`` must never be called on the pointer. + * \endverbatim + * + * @return a pointer to the internal UDT. + */ + const void *get_void_ptr() const; + + /// Get a mutable pointer to the UDT. + /** + * \verbatim embed:rst:leading-asterisk + * .. versionadded:: 2.15 + * + * This function will return a raw pointer + * to the internal UDT instance. Differently from + * :cpp:func:`~pagmo::topology::extract()`, this function + * does not require to pass the correct type + * in input. It is however the user's responsibility + * to cast the returned void pointer to the correct type. + * + * .. note:: + * + * The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime + * of ``this``, and ``delete`` must never be called on the pointer. + * \endverbatim + * + * @return a pointer to the internal UDT. + */ + void *get_void_ptr(); + // Serialization. template void save(Archive &ar, unsigned) const diff --git a/src/topology.cpp b/src/topology.cpp index 845cd7e4f..285e977f2 100644 --- a/src/topology.cpp +++ b/src/topology.cpp @@ -31,9 +31,11 @@ see https://www.gnu.org/licenses/. */ #include #include #include +#include #include #include +#include #include #include #include @@ -157,11 +159,39 @@ bgl_graph_t topology::to_bgl() const return ptr()->to_bgl(); } +/// Get the type of the UDT. +/** + * \verbatim embed:rst:leading-asterisk + * .. versionadded:: 2.15 + * + * This function will return the type + * of the UDT stored within this topology + * instance. + * \endverbatim + * + * @return the type of the UDT. + */ +std::type_index topology::get_type_index() const +{ + return ptr()->get_type_index(); +} + +const void *topology::get_void_ptr() const +{ + return ptr()->get_void_ptr(); +} + +void *topology::get_void_ptr() +{ + return ptr()->get_void_ptr(); +} + #if !defined(PAGMO_DOXYGEN_INVOKED) std::ostream &operator<<(std::ostream &os, const topology &t) { os << "Topology name: " << t.get_name(); + os << "\n\tC++ class name: " << detail::demangle_from_typeid(t.get_type_index().name()) << '\n'; const auto extra_str = t.get_extra_info(); if (!extra_str.empty()) { os << "\nExtra info:\n" << extra_str; diff --git a/tests/topology.cpp b/tests/topology.cpp index 67af00191..4f1126832 100644 --- a/tests/topology.cpp +++ b/tests/topology.cpp @@ -32,17 +32,21 @@ see https://www.gnu.org/licenses/. */ #include #include +#include #include #include #include #include #include +#include +#include #include #include #include #include +#include #include #include #include @@ -100,6 +104,14 @@ struct udt00 { int n_pushed = 0; }; +struct udt00a { + std::pair, vector_double> get_connections(std::size_t) const + { + return {{0, 1, 2}, {0.1, 0.2, 0.3}}; + } + void push_back() {} +}; + PAGMO_S11N_TOPOLOGY_EXPORT(udt00) struct udt01 { @@ -158,6 +170,7 @@ BOOST_AUTO_TEST_CASE(topology_basic_tests) BOOST_CHECK(t0.extract() == nullptr); BOOST_CHECK(static_cast(t0).extract() == nullptr); BOOST_CHECK(t0.get_name() == "udt00"); + BOOST_CHECK(topology{udt00a{}}.get_name() == detail::type_name()); BOOST_CHECK(t0.get_extra_info().empty()); t0.push_back(); @@ -321,6 +334,8 @@ BOOST_AUTO_TEST_CASE(topology_stream_test) BOOST_CHECK(boost::contains(str, "Topology name: udt00")); } + + std::cout << topology{} << '\n'; } BOOST_AUTO_TEST_CASE(topology_push_back_n_test) @@ -356,3 +371,23 @@ BOOST_AUTO_TEST_CASE(topology_to_bgl_test) BOOST_CHECK(boost::num_vertices(topology{udt01{}}.to_bgl()) == 0); } + +BOOST_AUTO_TEST_CASE(type_index) +{ + topology p0; + BOOST_CHECK(p0.get_type_index() == std::type_index(typeid(unconnected))); + p0 = topology{udt00a{}}; + BOOST_CHECK(p0.get_type_index() == std::type_index(typeid(udt00a))); +} + +BOOST_AUTO_TEST_CASE(get_void_ptr) +{ + topology p0; + BOOST_CHECK(p0.get_void_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_void_ptr() + == static_cast(p0).extract()); + p0 = topology{udt00a{}}; + BOOST_CHECK(p0.get_void_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_void_ptr() + == static_cast(p0).extract()); +} From 016c9f3d4e861eaad7f90ef762465d4053026608 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 28 Mar 2020 16:25:57 +0100 Subject: [PATCH 14/30] Ditto for the remaning UDx. --- include/pagmo/r_policy.hpp | 78 +++++++++++++++++++++++++++++++++++++- include/pagmo/s_policy.hpp | 78 +++++++++++++++++++++++++++++++++++++- src/r_policy.cpp | 32 +++++++++++++++- src/s_policy.cpp | 32 +++++++++++++++- tests/r_policy.cpp | 27 ++++++++++++- tests/s_policy.cpp | 27 ++++++++++++- 6 files changed, 268 insertions(+), 6 deletions(-) diff --git a/include/pagmo/r_policy.hpp b/include/pagmo/r_policy.hpp index 138b57d0f..fa49be55f 100644 --- a/include/pagmo/r_policy.hpp +++ b/include/pagmo/r_policy.hpp @@ -34,14 +34,18 @@ see https://www.gnu.org/licenses/. */ #include #include #include +#include #include #include #include #include +#include #include #include +#include +#include #include #include #include @@ -122,6 +126,9 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS r_pol_inner_base { const vector_double &, const individuals_group_t &) const = 0; virtual std::string get_name() const = 0; virtual std::string get_extra_info() const = 0; + virtual std::type_index get_type_index() const = 0; + virtual const void *get_void_ptr() const = 0; + virtual void *get_void_ptr() = 0; template void serialize(Archive &, unsigned) { @@ -169,7 +176,7 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS r_pol_inner final : r_pol_inner_base { template ::value, int> = 0> static std::string get_name_impl(const U &) { - return typeid(U).name(); + return detail::type_name(); } template ::value, int> = 0> static std::string get_extra_info_impl(const U &value) @@ -181,6 +188,20 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS r_pol_inner final : r_pol_inner_base { { return ""; } + // Get the type at runtime. + virtual std::type_index get_type_index() const override final + { + return std::type_index(typeid(T)); + } + // Raw getters for the internal instance. + virtual const void *get_void_ptr() const override final + { + return &m_value; + } + virtual void *get_void_ptr() override final + { + return &m_value; + } // Serialization template void serialize(Archive &ar, unsigned) @@ -245,14 +266,22 @@ class PAGMO_DLL_PUBLIC r_policy template const T *extract() const noexcept { +#if defined(PAGMO_PREFER_TYPEID_NAME_EXTRACT) + return detail::typeid_name_extract(*this); +#else auto p = dynamic_cast *>(ptr()); return p == nullptr ? nullptr : &(p->m_value); +#endif } template T *extract() noexcept { +#if defined(PAGMO_PREFER_TYPEID_NAME_EXTRACT) + return detail::typeid_name_extract(*this); +#else auto p = dynamic_cast *>(ptr()); return p == nullptr ? nullptr : &(p->m_value); +#endif } template bool is() const noexcept @@ -277,6 +306,53 @@ class PAGMO_DLL_PUBLIC r_policy // Check if the r_policy is valid. bool is_valid() const; + // Get the type at runtime. + std::type_index get_type_index() const; + + /// Get a const pointer to the UDRP. + /** + * \verbatim embed:rst:leading-asterisk + * .. versionadded:: 2.15 + * + * This function will return a raw const pointer + * to the internal UDRP instance. Differently from + * :cpp:func:`~pagmo::r_policy::extract()`, this function + * does not require to pass the correct type + * in input. It is however the user's responsibility + * to cast the returned void pointer to the correct type. + * + * .. note:: + * + * The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime + * of ``this``, and ``delete`` must never be called on the pointer. + * \endverbatim + * + * @return a pointer to the internal UDRP. + */ + const void *get_void_ptr() const; + + /// Get a mutable pointer to the UDRP. + /** + * \verbatim embed:rst:leading-asterisk + * .. versionadded:: 2.15 + * + * This function will return a raw pointer + * to the internal UDRP instance. Differently from + * :cpp:func:`~pagmo::r_policy::extract()`, this function + * does not require to pass the correct type + * in input. It is however the user's responsibility + * to cast the returned void pointer to the correct type. + * + * .. note:: + * + * The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime + * of ``this``, and ``delete`` must never be called on the pointer. + * \endverbatim + * + * @return a pointer to the internal UDRP. + */ + void *get_void_ptr(); + // Serialisation support. template void save(Archive &ar, unsigned) const diff --git a/include/pagmo/s_policy.hpp b/include/pagmo/s_policy.hpp index eeb8accb1..3f755f990 100644 --- a/include/pagmo/s_policy.hpp +++ b/include/pagmo/s_policy.hpp @@ -34,14 +34,18 @@ see https://www.gnu.org/licenses/. */ #include #include #include +#include #include #include #include #include +#include #include #include +#include +#include #include #include #include @@ -122,6 +126,9 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS s_pol_inner_base { const vector_double &) const = 0; virtual std::string get_name() const = 0; virtual std::string get_extra_info() const = 0; + virtual std::type_index get_type_index() const = 0; + virtual const void *get_void_ptr() const = 0; + virtual void *get_void_ptr() = 0; template void serialize(Archive &, unsigned) { @@ -169,7 +176,7 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS s_pol_inner final : s_pol_inner_base { template ::value, int> = 0> static std::string get_name_impl(const U &) { - return typeid(U).name(); + return detail::type_name(); } template ::value, int> = 0> static std::string get_extra_info_impl(const U &value) @@ -181,6 +188,20 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS s_pol_inner final : s_pol_inner_base { { return ""; } + // Get the type at runtime. + virtual std::type_index get_type_index() const override final + { + return std::type_index(typeid(T)); + } + // Raw getters for the internal instance. + virtual const void *get_void_ptr() const override final + { + return &m_value; + } + virtual void *get_void_ptr() override final + { + return &m_value; + } // Serialization template void serialize(Archive &ar, unsigned) @@ -245,14 +266,22 @@ class PAGMO_DLL_PUBLIC s_policy template const T *extract() const noexcept { +#if defined(PAGMO_PREFER_TYPEID_NAME_EXTRACT) + return detail::typeid_name_extract(*this); +#else auto p = dynamic_cast *>(ptr()); return p == nullptr ? nullptr : &(p->m_value); +#endif } template T *extract() noexcept { +#if defined(PAGMO_PREFER_TYPEID_NAME_EXTRACT) + return detail::typeid_name_extract(*this); +#else auto p = dynamic_cast *>(ptr()); return p == nullptr ? nullptr : &(p->m_value); +#endif } template bool is() const noexcept @@ -277,6 +306,53 @@ class PAGMO_DLL_PUBLIC s_policy // Check if the s_policy is valid. bool is_valid() const; + // Get the type at runtime. + std::type_index get_type_index() const; + + /// Get a const pointer to the UDSP. + /** + * \verbatim embed:rst:leading-asterisk + * .. versionadded:: 2.15 + * + * This function will return a raw const pointer + * to the internal UDSP instance. Differently from + * :cpp:func:`~pagmo::s_policy::extract()`, this function + * does not require to pass the correct type + * in input. It is however the user's responsibility + * to cast the returned void pointer to the correct type. + * + * .. note:: + * + * The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime + * of ``this``, and ``delete`` must never be called on the pointer. + * \endverbatim + * + * @return a pointer to the internal UDSP. + */ + const void *get_void_ptr() const; + + /// Get a mutable pointer to the UDSP. + /** + * \verbatim embed:rst:leading-asterisk + * .. versionadded:: 2.15 + * + * This function will return a raw pointer + * to the internal UDSP instance. Differently from + * :cpp:func:`~pagmo::s_policy::extract()`, this function + * does not require to pass the correct type + * in input. It is however the user's responsibility + * to cast the returned void pointer to the correct type. + * + * .. note:: + * + * The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime + * of ``this``, and ``delete`` must never be called on the pointer. + * \endverbatim + * + * @return a pointer to the internal UDSP. + */ + void *get_void_ptr(); + // Serialisation support. template void save(Archive &ar, unsigned) const diff --git a/src/r_policy.cpp b/src/r_policy.cpp index a27110e5b..27fdd1ffc 100644 --- a/src/r_policy.cpp +++ b/src/r_policy.cpp @@ -32,8 +32,10 @@ see https://www.gnu.org/licenses/. */ #include #include #include +#include #include +#include #include #include #include @@ -236,12 +238,40 @@ bool r_policy::is_valid() const return static_cast(m_ptr); } +/// Get the type of the UDRP. +/** + * \verbatim embed:rst:leading-asterisk + * .. versionadded:: 2.15 + * + * This function will return the type + * of the UDRP stored within this policy + * instance. + * \endverbatim + * + * @return the type of the UDRP. + */ +std::type_index r_policy::get_type_index() const +{ + return ptr()->get_type_index(); +} + +const void *r_policy::get_void_ptr() const +{ + return ptr()->get_void_ptr(); +} + +void *r_policy::get_void_ptr() +{ + return ptr()->get_void_ptr(); +} + #if !defined(PAGMO_DOXYGEN_INVOKED) // Stream operator. std::ostream &operator<<(std::ostream &os, const r_policy &r) { - os << "Replacement policy name: " << r.get_name() << '\n'; + os << "Replacement policy name: " << r.get_name(); + os << "\n\tC++ class name: " << detail::demangle_from_typeid(r.get_type_index().name()) << '\n'; const auto extra_str = r.get_extra_info(); if (!extra_str.empty()) { os << "\nExtra info:\n" << extra_str << '\n'; diff --git a/src/s_policy.cpp b/src/s_policy.cpp index 73487329b..a56c9d35a 100644 --- a/src/s_policy.cpp +++ b/src/s_policy.cpp @@ -32,8 +32,10 @@ see https://www.gnu.org/licenses/. */ #include #include #include +#include #include +#include #include #include #include @@ -219,12 +221,40 @@ bool s_policy::is_valid() const return static_cast(m_ptr); } +/// Get the type of the UDSP. +/** + * \verbatim embed:rst:leading-asterisk + * .. versionadded:: 2.15 + * + * This function will return the type + * of the UDSP stored within this policy + * instance. + * \endverbatim + * + * @return the type of the UDSP. + */ +std::type_index s_policy::get_type_index() const +{ + return ptr()->get_type_index(); +} + +const void *s_policy::get_void_ptr() const +{ + return ptr()->get_void_ptr(); +} + +void *s_policy::get_void_ptr() +{ + return ptr()->get_void_ptr(); +} + #if !defined(PAGMO_DOXYGEN_INVOKED) // Stream operator. std::ostream &operator<<(std::ostream &os, const s_policy &s) { - os << "Selection policy name: " << s.get_name() << '\n'; + os << "Selection policy name: " << s.get_name(); + os << "\n\tC++ class name: " << detail::demangle_from_typeid(s.get_type_index().name()) << '\n'; const auto extra_str = s.get_extra_info(); if (!extra_str.empty()) { os << "\nExtra info:\n" << extra_str << '\n'; diff --git a/tests/r_policy.cpp b/tests/r_policy.cpp index dd0751295..c6d1d2765 100644 --- a/tests/r_policy.cpp +++ b/tests/r_policy.cpp @@ -38,17 +38,21 @@ see https://www.gnu.org/licenses/. */ #include #include +#include #include #include #include #include #include #include +#include +#include #include #include #include +#include #include #include #include @@ -148,7 +152,7 @@ BOOST_AUTO_TEST_CASE(basic_tests) BOOST_CHECK(!r.get_extra_info().empty()); BOOST_CHECK(r_policy(udrp1{}).get_extra_info().empty()); - BOOST_CHECK(!r_policy(udrp1{}).get_name().empty()); + BOOST_CHECK(r_policy(udrp1{}).get_name() == detail::type_name()); // Constructors, assignments. // Generic constructor with copy. @@ -212,6 +216,8 @@ BOOST_AUTO_TEST_CASE(basic_tests) BOOST_CHECK(before == boost::lexical_cast(r)); BOOST_CHECK(r.is()); } + + std::cout << r_policy{} << '\n'; } BOOST_AUTO_TEST_CASE(optional_tests) @@ -586,3 +592,22 @@ BOOST_AUTO_TEST_CASE(generic_assignment) BOOST_CHECK((!std::is_assignable::value)); BOOST_CHECK((!std::is_assignable::value)); } + +BOOST_AUTO_TEST_CASE(type_index) +{ + r_policy p0; + BOOST_CHECK(p0.get_type_index() == std::type_index(typeid(fair_replace))); + p0 = r_policy{udrp1{}}; + BOOST_CHECK(p0.get_type_index() == std::type_index(typeid(udrp1))); +} + +BOOST_AUTO_TEST_CASE(get_void_ptr) +{ + r_policy p0; + BOOST_CHECK(p0.get_void_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_void_ptr() + == static_cast(p0).extract()); + p0 = r_policy{udrp1{}}; + BOOST_CHECK(p0.get_void_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_void_ptr() == static_cast(p0).extract()); +} diff --git a/tests/s_policy.cpp b/tests/s_policy.cpp index b999f9100..d656add47 100644 --- a/tests/s_policy.cpp +++ b/tests/s_policy.cpp @@ -38,17 +38,21 @@ see https://www.gnu.org/licenses/. */ #include #include +#include #include #include #include #include #include #include +#include +#include #include #include #include +#include #include #include #include @@ -148,7 +152,7 @@ BOOST_AUTO_TEST_CASE(basic_tests) BOOST_CHECK(!r.get_extra_info().empty()); BOOST_CHECK(s_policy(udsp1{}).get_extra_info().empty()); - BOOST_CHECK(!s_policy(udsp1{}).get_name().empty()); + BOOST_CHECK(s_policy(udsp1{}).get_name() == detail::type_name()); // Constructors, assignments. // Generic constructor with copy. @@ -212,6 +216,8 @@ BOOST_AUTO_TEST_CASE(basic_tests) BOOST_CHECK(before == boost::lexical_cast(r)); BOOST_CHECK(r.is()); } + + std::cout << s_policy{} << '\n'; } BOOST_AUTO_TEST_CASE(optional_tests) @@ -547,3 +553,22 @@ BOOST_AUTO_TEST_CASE(generic_assignment) BOOST_CHECK((!std::is_assignable::value)); BOOST_CHECK((!std::is_assignable::value)); } + +BOOST_AUTO_TEST_CASE(type_index) +{ + s_policy p0; + BOOST_CHECK(p0.get_type_index() == std::type_index(typeid(select_best))); + p0 = s_policy{udsp1{}}; + BOOST_CHECK(p0.get_type_index() == std::type_index(typeid(udsp1))); +} + +BOOST_AUTO_TEST_CASE(get_void_ptr) +{ + s_policy p0; + BOOST_CHECK(p0.get_void_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_void_ptr() + == static_cast(p0).extract()); + p0 = s_policy{udsp1{}}; + BOOST_CHECK(p0.get_void_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_void_ptr() == static_cast(p0).extract()); +} From 8e2923b748068e25f943128b221862131d0ac9cc Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 28 Mar 2020 16:26:24 +0100 Subject: [PATCH 15/30] Try downgrading doxy. --- tools/circleci_bionic_gcc7_conda_docs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/circleci_bionic_gcc7_conda_docs.sh b/tools/circleci_bionic_gcc7_conda_docs.sh index c475f4735..ec955f469 100644 --- a/tools/circleci_bionic_gcc7_conda_docs.sh +++ b/tools/circleci_bionic_gcc7_conda_docs.sh @@ -15,7 +15,7 @@ export deps_dir=$HOME/local export PATH="$HOME/miniconda/bin:$PATH" bash miniconda.sh -b -p $HOME/miniconda conda config --add channels conda-forge --force -conda_pkgs="cmake eigen nlopt ipopt boost-cpp tbb tbb-devel python=3.7 sphinx sphinx_rtd_theme breathe doxygen graphviz" +conda_pkgs="cmake eigen nlopt ipopt boost-cpp tbb tbb-devel python=3.7 sphinx sphinx_rtd_theme breathe doxygen=1.8.15 graphviz" conda create -q -p $deps_dir -y source activate $deps_dir conda install $conda_pkgs -y From 5acaa2d5cd96b727315caaeec63af8f96b093375 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 28 Mar 2020 16:32:36 +0100 Subject: [PATCH 16/30] MSVC workaround. --- tests/island.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/island.cpp b/tests/island.cpp index d1d63cda9..1cf105cd9 100644 --- a/tests/island.cpp +++ b/tests/island.cpp @@ -543,7 +543,9 @@ BOOST_AUTO_TEST_CASE(island_extract) BOOST_CHECK((std::is_same())>::value)); BOOST_CHECK((std::is_same(isl).extract())>::value)); BOOST_CHECK(isl.is()); +#if !defined(_MSC_VER) || defined(__clang__) BOOST_CHECK(isl.extract() == nullptr); +#endif } // Constructors with bfe arguments. From 657716ac129f7b266e29888e1ba6da452abd2789 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 28 Mar 2020 16:33:38 +0100 Subject: [PATCH 17/30] Revert "Try downgrading doxy." This reverts commit 8e2923b748068e25f943128b221862131d0ac9cc. --- tools/circleci_bionic_gcc7_conda_docs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/circleci_bionic_gcc7_conda_docs.sh b/tools/circleci_bionic_gcc7_conda_docs.sh index ec955f469..c475f4735 100644 --- a/tools/circleci_bionic_gcc7_conda_docs.sh +++ b/tools/circleci_bionic_gcc7_conda_docs.sh @@ -15,7 +15,7 @@ export deps_dir=$HOME/local export PATH="$HOME/miniconda/bin:$PATH" bash miniconda.sh -b -p $HOME/miniconda conda config --add channels conda-forge --force -conda_pkgs="cmake eigen nlopt ipopt boost-cpp tbb tbb-devel python=3.7 sphinx sphinx_rtd_theme breathe doxygen=1.8.15 graphviz" +conda_pkgs="cmake eigen nlopt ipopt boost-cpp tbb tbb-devel python=3.7 sphinx sphinx_rtd_theme breathe doxygen graphviz" conda create -q -p $deps_dir -y source activate $deps_dir conda install $conda_pkgs -y From 94d4b680fbb397aa21a13847db20bb3800c7b593 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 28 Mar 2020 16:54:21 +0100 Subject: [PATCH 18/30] Another MSVC bit. --- tests/island.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/island.cpp b/tests/island.cpp index 1cf105cd9..b1a7b3f16 100644 --- a/tests/island.cpp +++ b/tests/island.cpp @@ -532,7 +532,9 @@ BOOST_AUTO_TEST_CASE(island_extract) BOOST_CHECK((std::is_same(isl).extract())>::value)); BOOST_CHECK(isl.is()); +#if !defined(_MSC_VER) || defined(__clang__) BOOST_CHECK(isl.extract() == nullptr); +#endif BOOST_CHECK(isl.extract() == nullptr); BOOST_CHECK(!isl.is()); isl = island(udi_01{}, stateful_algo{}, null_problem{}, 20); From 8d3888d4aba9c1584bd6307df1e82d2e6e4142bb Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 28 Mar 2020 18:36:22 +0100 Subject: [PATCH 19/30] Another go at doxy pin. --- tools/circleci_bionic_gcc7_conda_docs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/circleci_bionic_gcc7_conda_docs.sh b/tools/circleci_bionic_gcc7_conda_docs.sh index c475f4735..abcef8305 100644 --- a/tools/circleci_bionic_gcc7_conda_docs.sh +++ b/tools/circleci_bionic_gcc7_conda_docs.sh @@ -15,7 +15,7 @@ export deps_dir=$HOME/local export PATH="$HOME/miniconda/bin:$PATH" bash miniconda.sh -b -p $HOME/miniconda conda config --add channels conda-forge --force -conda_pkgs="cmake eigen nlopt ipopt boost-cpp tbb tbb-devel python=3.7 sphinx sphinx_rtd_theme breathe doxygen graphviz" +conda_pkgs="cmake eigen nlopt ipopt boost-cpp tbb tbb-devel python=3.7 sphinx sphinx_rtd_theme breathe doxygen=1.8.14 graphviz" conda create -q -p $deps_dir -y source activate $deps_dir conda install $conda_pkgs -y From 1e6e33f4c47e027df59afb946a3714bfc9936446 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 28 Mar 2020 20:34:29 +0100 Subject: [PATCH 20/30] Revert "Another go at doxy pin." This reverts commit 8d3888d4aba9c1584bd6307df1e82d2e6e4142bb. --- tools/circleci_bionic_gcc7_conda_docs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/circleci_bionic_gcc7_conda_docs.sh b/tools/circleci_bionic_gcc7_conda_docs.sh index abcef8305..c475f4735 100644 --- a/tools/circleci_bionic_gcc7_conda_docs.sh +++ b/tools/circleci_bionic_gcc7_conda_docs.sh @@ -15,7 +15,7 @@ export deps_dir=$HOME/local export PATH="$HOME/miniconda/bin:$PATH" bash miniconda.sh -b -p $HOME/miniconda conda config --add channels conda-forge --force -conda_pkgs="cmake eigen nlopt ipopt boost-cpp tbb tbb-devel python=3.7 sphinx sphinx_rtd_theme breathe doxygen=1.8.14 graphviz" +conda_pkgs="cmake eigen nlopt ipopt boost-cpp tbb tbb-devel python=3.7 sphinx sphinx_rtd_theme breathe doxygen graphviz" conda create -q -p $deps_dir -y source activate $deps_dir conda install $conda_pkgs -y From 1c2e027b7b23384ca9cbc9b9fd9204a161b96cc7 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 28 Mar 2020 22:31:19 +0100 Subject: [PATCH 21/30] Doc fixes. --- doc/sphinx/docs/cpp/bfe.rst | 38 +++++++++++++++++++++++++++++ doc/sphinx/docs/cpp/r_policy.rst | 38 +++++++++++++++++++++++++++++ doc/sphinx/docs/cpp/s_policy.rst | 38 +++++++++++++++++++++++++++++ doc/sphinx/docs/cpp/topology.rst | 38 +++++++++++++++++++++++++++++ include/pagmo/algorithm.hpp | 5 ++++ include/pagmo/bfe.hpp | 42 ++------------------------------ include/pagmo/island.hpp | 5 ++++ include/pagmo/problem.hpp | 5 ++++ include/pagmo/r_policy.hpp | 42 ++------------------------------ include/pagmo/s_policy.hpp | 42 ++------------------------------ include/pagmo/topology.hpp | 42 ++------------------------------ src/bfe.cpp | 12 --------- src/r_policy.cpp | 13 +--------- src/s_policy.cpp | 13 +--------- src/topology.cpp | 13 +--------- 15 files changed, 178 insertions(+), 208 deletions(-) diff --git a/doc/sphinx/docs/cpp/bfe.rst b/doc/sphinx/docs/cpp/bfe.rst index 1a6ffc02d..10c02cf1c 100644 --- a/doc/sphinx/docs/cpp/bfe.rst +++ b/doc/sphinx/docs/cpp/bfe.rst @@ -217,6 +217,44 @@ Batch fitness evaluator :return: ``false`` if *this* was moved from, ``true`` otherwise. + .. cpp:function:: std::type_index get_type_index() const + + .. versionadded:: 2.15 + + Get the type of the UDBFE. + + This function will return the type + of the UDBFE stored within this :cpp:class:`~pagmo::bfe` + instance. + + :return: the type of the UDBFE. + + .. cpp:function:: const void *get_void_ptr() const + .. cpp:function:: void *get_void_ptr() + + .. versionadded:: 2.15 + + Get a pointer to the UDBFE. + + These functions will return a raw (const) pointer + to the internal UDBFE instance. Differently from + the :cpp:func:`~pagmo::bfe::extract()` overloads, these functions + do not require to pass the correct type + in input. It is however the user's responsibility + to cast the returned void pointer to the correct type. + + .. note:: + + The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime + of ``this``, and ``delete`` must never be called on the pointer. + + .. note:: + + The ability to extract a mutable pointer is provided only in order to allow to call non-const + methods on the internal UDBFE instance. Assigning a new UDBFE via this pointer is undefined behaviour. + + :return: a pointer to the internal UDBFE. + .. cpp:function:: template void save(Archive &ar, unsigned) const .. cpp:function:: template void load(Archive &ar, unsigned) diff --git a/doc/sphinx/docs/cpp/r_policy.rst b/doc/sphinx/docs/cpp/r_policy.rst index d853d1903..b4d725054 100644 --- a/doc/sphinx/docs/cpp/r_policy.rst +++ b/doc/sphinx/docs/cpp/r_policy.rst @@ -218,6 +218,44 @@ Replacement policy :return: ``false`` if *this* was moved from, ``true`` otherwise. + .. cpp:function:: std::type_index get_type_index() const + + .. versionadded:: 2.15 + + Get the type of the UDRP. + + This function will return the type + of the UDRP stored within this :cpp:class:`~pagmo::r_policy` + instance. + + :return: the type of the UDRP. + + .. cpp:function:: const void *get_void_ptr() const + .. cpp:function:: void *get_void_ptr() + + .. versionadded:: 2.15 + + Get a pointer to the UDRP. + + These functions will return a raw (const) pointer + to the internal UDRP instance. Differently from + the :cpp:func:`~pagmo::r_policy::extract()` overloads, these functions + do not require to pass the correct type + in input. It is however the user's responsibility + to cast the returned void pointer to the correct type. + + .. note:: + + The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime + of ``this``, and ``delete`` must never be called on the pointer. + + .. note:: + + The ability to extract a mutable pointer is provided only in order to allow to call non-const + methods on the internal UDRP instance. Assigning a new UDRP via this pointer is undefined behaviour. + + :return: a pointer to the internal UDRP. + .. cpp:function:: template void save(Archive &ar, unsigned) const .. cpp:function:: template void load(Archive &ar, unsigned) diff --git a/doc/sphinx/docs/cpp/s_policy.rst b/doc/sphinx/docs/cpp/s_policy.rst index 8094406ea..827c9e6e3 100644 --- a/doc/sphinx/docs/cpp/s_policy.rst +++ b/doc/sphinx/docs/cpp/s_policy.rst @@ -211,6 +211,44 @@ Selection policy :return: ``false`` if *this* was moved from, ``true`` otherwise. + .. cpp:function:: std::type_index get_type_index() const + + .. versionadded:: 2.15 + + Get the type of the UDSP. + + This function will return the type + of the UDSP stored within this :cpp:class:`~pagmo::s_policy` + instance. + + :return: the type of the UDSP. + + .. cpp:function:: const void *get_void_ptr() const + .. cpp:function:: void *get_void_ptr() + + .. versionadded:: 2.15 + + Get a pointer to the UDSP. + + These functions will return a raw (const) pointer + to the internal UDSP instance. Differently from + the :cpp:func:`~pagmo::s_policy::extract()` overloads, these functions + do not require to pass the correct type + in input. It is however the user's responsibility + to cast the returned void pointer to the correct type. + + .. note:: + + The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime + of ``this``, and ``delete`` must never be called on the pointer. + + .. note:: + + The ability to extract a mutable pointer is provided only in order to allow to call non-const + methods on the internal UDSP instance. Assigning a new UDSP via this pointer is undefined behaviour. + + :return: a pointer to the internal UDSP. + .. cpp:function:: template void save(Archive &ar, unsigned) const .. cpp:function:: template void load(Archive &ar, unsigned) diff --git a/doc/sphinx/docs/cpp/topology.rst b/doc/sphinx/docs/cpp/topology.rst index 57c6fdcbe..d1d1057c2 100644 --- a/doc/sphinx/docs/cpp/topology.rst +++ b/doc/sphinx/docs/cpp/topology.rst @@ -240,6 +240,44 @@ Topology :return: ``false`` if *this* was moved from, ``true`` otherwise. + .. cpp:function:: std::type_index get_type_index() const + + .. versionadded:: 2.15 + + Get the type of the UDT. + + This function will return the type + of the UDT stored within this :cpp:class:`~pagmo::topology` + instance. + + :return: the type of the UDT. + + .. cpp:function:: const void *get_void_ptr() const + .. cpp:function:: void *get_void_ptr() + + .. versionadded:: 2.15 + + Get a pointer to the UDT. + + These functions will return a raw (const) pointer + to the internal UDT instance. Differently from + the :cpp:func:`~pagmo::topology::extract()` overloads, these functions + do not require to pass the correct type + in input. It is however the user's responsibility + to cast the returned void pointer to the correct type. + + .. note:: + + The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime + of ``this``, and ``delete`` must never be called on the pointer. + + .. note:: + + The ability to extract a mutable pointer is provided only in order to allow to call non-const + methods on the internal UDT instance. Assigning a new UDT via this pointer is undefined behaviour. + + :return: a pointer to the internal UDT. + .. cpp:function:: template void save(Archive &ar, unsigned) const .. cpp:function:: template void load(Archive &ar, unsigned) diff --git a/include/pagmo/algorithm.hpp b/include/pagmo/algorithm.hpp index 4b127ff71..540f31237 100644 --- a/include/pagmo/algorithm.hpp +++ b/include/pagmo/algorithm.hpp @@ -709,6 +709,11 @@ class PAGMO_DLL_PUBLIC algorithm * * The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime * of ``this``, and ``delete`` must never be called on the pointer. + * + * .. note:: + * + * The ability to extract a mutable pointer is provided only in order to allow to call non-const + * methods on the internal UDA instance. Assigning a new UDA via this pointer is undefined behaviour. * \endverbatim * * @return a pointer to the internal UDA. diff --git a/include/pagmo/bfe.hpp b/include/pagmo/bfe.hpp index d601498dc..758164f12 100644 --- a/include/pagmo/bfe.hpp +++ b/include/pagmo/bfe.hpp @@ -339,48 +339,10 @@ class PAGMO_DLL_PUBLIC bfe // Get the type at runtime. std::type_index get_type_index() const; - /// Get a const pointer to the UDBFE. - /** - * \verbatim embed:rst:leading-asterisk - * .. versionadded:: 2.15 - * - * This function will return a raw const pointer - * to the internal UDBFE instance. Differently from - * :cpp:func:`~pagmo::bfe::extract()`, this function - * does not require to pass the correct type - * in input. It is however the user's responsibility - * to cast the returned void pointer to the correct type. - * - * .. note:: - * - * The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime - * of ``this``, and ``delete`` must never be called on the pointer. - * \endverbatim - * - * @return a pointer to the internal UDBFE. - */ + // Get a const pointer to the UDBFE. const void *get_void_ptr() const; - /// Get a mutable pointer to the UDBFE. - /** - * \verbatim embed:rst:leading-asterisk - * .. versionadded:: 2.15 - * - * This function will return a raw pointer - * to the internal UDBFE instance. Differently from - * :cpp:func:`~pagmo::bfe::extract()`, this function - * does not require to pass the correct type - * in input. It is however the user's responsibility - * to cast the returned void pointer to the correct type. - * - * .. note:: - * - * The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime - * of ``this``, and ``delete`` must never be called on the pointer. - * \endverbatim - * - * @return a pointer to the internal UDBFE. - */ + // Get a mutable pointer to the UDBFE. void *get_void_ptr(); // Serialisation support. diff --git a/include/pagmo/island.hpp b/include/pagmo/island.hpp index 113d0f338..8f03cb127 100644 --- a/include/pagmo/island.hpp +++ b/include/pagmo/island.hpp @@ -1176,6 +1176,11 @@ class PAGMO_DLL_PUBLIC island * * The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime * of ``this``, and ``delete`` must never be called on the pointer. + * + * .. note:: + * + * The ability to extract a mutable pointer is provided only in order to allow to call non-const + * methods on the internal UDI instance. Assigning a new UDI via this pointer is undefined behaviour. * \endverbatim * * @return a pointer to the internal UDI. diff --git a/include/pagmo/problem.hpp b/include/pagmo/problem.hpp index 2967bc957..248b399d6 100644 --- a/include/pagmo/problem.hpp +++ b/include/pagmo/problem.hpp @@ -1661,6 +1661,11 @@ class PAGMO_DLL_PUBLIC problem * * The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime * of ``this``, and ``delete`` must never be called on the pointer. + * + * .. note:: + * + * The ability to extract a mutable pointer is provided only in order to allow to call non-const + * methods on the internal UDP instance. Assigning a new UDP via this pointer is undefined behaviour. * \endverbatim * * @return a pointer to the internal UDP. diff --git a/include/pagmo/r_policy.hpp b/include/pagmo/r_policy.hpp index fa49be55f..d5afa743f 100644 --- a/include/pagmo/r_policy.hpp +++ b/include/pagmo/r_policy.hpp @@ -309,48 +309,10 @@ class PAGMO_DLL_PUBLIC r_policy // Get the type at runtime. std::type_index get_type_index() const; - /// Get a const pointer to the UDRP. - /** - * \verbatim embed:rst:leading-asterisk - * .. versionadded:: 2.15 - * - * This function will return a raw const pointer - * to the internal UDRP instance. Differently from - * :cpp:func:`~pagmo::r_policy::extract()`, this function - * does not require to pass the correct type - * in input. It is however the user's responsibility - * to cast the returned void pointer to the correct type. - * - * .. note:: - * - * The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime - * of ``this``, and ``delete`` must never be called on the pointer. - * \endverbatim - * - * @return a pointer to the internal UDRP. - */ + // Get a const pointer to the UDRP. const void *get_void_ptr() const; - /// Get a mutable pointer to the UDRP. - /** - * \verbatim embed:rst:leading-asterisk - * .. versionadded:: 2.15 - * - * This function will return a raw pointer - * to the internal UDRP instance. Differently from - * :cpp:func:`~pagmo::r_policy::extract()`, this function - * does not require to pass the correct type - * in input. It is however the user's responsibility - * to cast the returned void pointer to the correct type. - * - * .. note:: - * - * The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime - * of ``this``, and ``delete`` must never be called on the pointer. - * \endverbatim - * - * @return a pointer to the internal UDRP. - */ + // Get a mutable pointer to the UDRP. void *get_void_ptr(); // Serialisation support. diff --git a/include/pagmo/s_policy.hpp b/include/pagmo/s_policy.hpp index 3f755f990..f833c8926 100644 --- a/include/pagmo/s_policy.hpp +++ b/include/pagmo/s_policy.hpp @@ -309,48 +309,10 @@ class PAGMO_DLL_PUBLIC s_policy // Get the type at runtime. std::type_index get_type_index() const; - /// Get a const pointer to the UDSP. - /** - * \verbatim embed:rst:leading-asterisk - * .. versionadded:: 2.15 - * - * This function will return a raw const pointer - * to the internal UDSP instance. Differently from - * :cpp:func:`~pagmo::s_policy::extract()`, this function - * does not require to pass the correct type - * in input. It is however the user's responsibility - * to cast the returned void pointer to the correct type. - * - * .. note:: - * - * The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime - * of ``this``, and ``delete`` must never be called on the pointer. - * \endverbatim - * - * @return a pointer to the internal UDSP. - */ + // Get a const pointer to the UDSP. const void *get_void_ptr() const; - /// Get a mutable pointer to the UDSP. - /** - * \verbatim embed:rst:leading-asterisk - * .. versionadded:: 2.15 - * - * This function will return a raw pointer - * to the internal UDSP instance. Differently from - * :cpp:func:`~pagmo::s_policy::extract()`, this function - * does not require to pass the correct type - * in input. It is however the user's responsibility - * to cast the returned void pointer to the correct type. - * - * .. note:: - * - * The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime - * of ``this``, and ``delete`` must never be called on the pointer. - * \endverbatim - * - * @return a pointer to the internal UDSP. - */ + // Get a mutable pointer to the UDSP. void *get_void_ptr(); // Serialisation support. diff --git a/include/pagmo/topology.hpp b/include/pagmo/topology.hpp index d76acdefc..68cd422c5 100644 --- a/include/pagmo/topology.hpp +++ b/include/pagmo/topology.hpp @@ -385,48 +385,10 @@ class PAGMO_DLL_PUBLIC topology // Get the type at runtime. std::type_index get_type_index() const; - /// Get a const pointer to the UDT. - /** - * \verbatim embed:rst:leading-asterisk - * .. versionadded:: 2.15 - * - * This function will return a raw const pointer - * to the internal UDT instance. Differently from - * :cpp:func:`~pagmo::topology::extract()`, this function - * does not require to pass the correct type - * in input. It is however the user's responsibility - * to cast the returned void pointer to the correct type. - * - * .. note:: - * - * The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime - * of ``this``, and ``delete`` must never be called on the pointer. - * \endverbatim - * - * @return a pointer to the internal UDT. - */ + // Get a const pointer to the UDT. const void *get_void_ptr() const; - /// Get a mutable pointer to the UDT. - /** - * \verbatim embed:rst:leading-asterisk - * .. versionadded:: 2.15 - * - * This function will return a raw pointer - * to the internal UDT instance. Differently from - * :cpp:func:`~pagmo::topology::extract()`, this function - * does not require to pass the correct type - * in input. It is however the user's responsibility - * to cast the returned void pointer to the correct type. - * - * .. note:: - * - * The returned value is a raw non-owning pointer: the lifetime of the pointee is tied to the lifetime - * of ``this``, and ``delete`` must never be called on the pointer. - * \endverbatim - * - * @return a pointer to the internal UDT. - */ + // Get a mutable pointer to the UDT. void *get_void_ptr(); // Serialization. diff --git a/src/bfe.cpp b/src/bfe.cpp index d5c096b54..8ec257d5d 100644 --- a/src/bfe.cpp +++ b/src/bfe.cpp @@ -121,18 +121,6 @@ bool bfe::is_valid() const return static_cast(m_ptr); } -/// Get the type of the UDBFE. -/** - * \verbatim embed:rst:leading-asterisk - * .. versionadded:: 2.15 - * - * This function will return the type - * of the UDBFE stored within this bfe - * instance. - * \endverbatim - * - * @return the type of the UDBFE. - */ std::type_index bfe::get_type_index() const { return ptr()->get_type_index(); diff --git a/src/r_policy.cpp b/src/r_policy.cpp index 27fdd1ffc..86275d007 100644 --- a/src/r_policy.cpp +++ b/src/r_policy.cpp @@ -238,18 +238,7 @@ bool r_policy::is_valid() const return static_cast(m_ptr); } -/// Get the type of the UDRP. -/** - * \verbatim embed:rst:leading-asterisk - * .. versionadded:: 2.15 - * - * This function will return the type - * of the UDRP stored within this policy - * instance. - * \endverbatim - * - * @return the type of the UDRP. - */ +// Get the type of the UDRP. std::type_index r_policy::get_type_index() const { return ptr()->get_type_index(); diff --git a/src/s_policy.cpp b/src/s_policy.cpp index a56c9d35a..0eaeb43f4 100644 --- a/src/s_policy.cpp +++ b/src/s_policy.cpp @@ -221,18 +221,7 @@ bool s_policy::is_valid() const return static_cast(m_ptr); } -/// Get the type of the UDSP. -/** - * \verbatim embed:rst:leading-asterisk - * .. versionadded:: 2.15 - * - * This function will return the type - * of the UDSP stored within this policy - * instance. - * \endverbatim - * - * @return the type of the UDSP. - */ +// Get the type of the UDSP. std::type_index s_policy::get_type_index() const { return ptr()->get_type_index(); diff --git a/src/topology.cpp b/src/topology.cpp index 285e977f2..8af15fb53 100644 --- a/src/topology.cpp +++ b/src/topology.cpp @@ -159,18 +159,7 @@ bgl_graph_t topology::to_bgl() const return ptr()->to_bgl(); } -/// Get the type of the UDT. -/** - * \verbatim embed:rst:leading-asterisk - * .. versionadded:: 2.15 - * - * This function will return the type - * of the UDT stored within this topology - * instance. - * \endverbatim - * - * @return the type of the UDT. - */ +// Get the type of the UDT. std::type_index topology::get_type_index() const { return ptr()->get_type_index(); From 0740804718e5755af40942c5743c6fbc2009bf7e Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 28 Mar 2020 22:34:19 +0100 Subject: [PATCH 22/30] get_void_ptr() -> get_ptr() --- doc/sphinx/docs/cpp/bfe.rst | 4 ++-- doc/sphinx/docs/cpp/r_policy.rst | 4 ++-- doc/sphinx/docs/cpp/s_policy.rst | 4 ++-- doc/sphinx/docs/cpp/topology.rst | 4 ++-- include/pagmo/algorithm.hpp | 12 ++++++------ include/pagmo/bfe.hpp | 12 ++++++------ include/pagmo/detail/typeid_name_extract.hpp | 2 +- include/pagmo/island.hpp | 12 ++++++------ include/pagmo/problem.hpp | 12 ++++++------ include/pagmo/r_policy.hpp | 12 ++++++------ include/pagmo/s_policy.hpp | 12 ++++++------ include/pagmo/topology.hpp | 12 ++++++------ src/algorithm.cpp | 8 ++++---- src/bfe.cpp | 8 ++++---- src/island.cpp | 8 ++++---- src/problem.cpp | 8 ++++---- src/r_policy.cpp | 8 ++++---- src/s_policy.cpp | 8 ++++---- src/topology.cpp | 8 ++++---- tests/algorithm.cpp | 11 +++++------ tests/bfe.cpp | 10 +++++----- tests/island.cpp | 11 +++++------ tests/problem.cpp | 11 +++++------ tests/r_policy.cpp | 10 +++++----- tests/s_policy.cpp | 10 +++++----- tests/topology.cpp | 11 +++++------ 26 files changed, 114 insertions(+), 118 deletions(-) diff --git a/doc/sphinx/docs/cpp/bfe.rst b/doc/sphinx/docs/cpp/bfe.rst index 10c02cf1c..a44d6fc30 100644 --- a/doc/sphinx/docs/cpp/bfe.rst +++ b/doc/sphinx/docs/cpp/bfe.rst @@ -229,8 +229,8 @@ Batch fitness evaluator :return: the type of the UDBFE. - .. cpp:function:: const void *get_void_ptr() const - .. cpp:function:: void *get_void_ptr() + .. cpp:function:: const void *get_ptr() const + .. cpp:function:: void *get_ptr() .. versionadded:: 2.15 diff --git a/doc/sphinx/docs/cpp/r_policy.rst b/doc/sphinx/docs/cpp/r_policy.rst index b4d725054..4a2af8b98 100644 --- a/doc/sphinx/docs/cpp/r_policy.rst +++ b/doc/sphinx/docs/cpp/r_policy.rst @@ -230,8 +230,8 @@ Replacement policy :return: the type of the UDRP. - .. cpp:function:: const void *get_void_ptr() const - .. cpp:function:: void *get_void_ptr() + .. cpp:function:: const void *get_ptr() const + .. cpp:function:: void *get_ptr() .. versionadded:: 2.15 diff --git a/doc/sphinx/docs/cpp/s_policy.rst b/doc/sphinx/docs/cpp/s_policy.rst index 827c9e6e3..c527a4e2c 100644 --- a/doc/sphinx/docs/cpp/s_policy.rst +++ b/doc/sphinx/docs/cpp/s_policy.rst @@ -223,8 +223,8 @@ Selection policy :return: the type of the UDSP. - .. cpp:function:: const void *get_void_ptr() const - .. cpp:function:: void *get_void_ptr() + .. cpp:function:: const void *get_ptr() const + .. cpp:function:: void *get_ptr() .. versionadded:: 2.15 diff --git a/doc/sphinx/docs/cpp/topology.rst b/doc/sphinx/docs/cpp/topology.rst index d1d1057c2..cfe719e1c 100644 --- a/doc/sphinx/docs/cpp/topology.rst +++ b/doc/sphinx/docs/cpp/topology.rst @@ -252,8 +252,8 @@ Topology :return: the type of the UDT. - .. cpp:function:: const void *get_void_ptr() const - .. cpp:function:: void *get_void_ptr() + .. cpp:function:: const void *get_ptr() const + .. cpp:function:: void *get_ptr() .. versionadded:: 2.15 diff --git a/include/pagmo/algorithm.hpp b/include/pagmo/algorithm.hpp index 540f31237..3ee9a7fab 100644 --- a/include/pagmo/algorithm.hpp +++ b/include/pagmo/algorithm.hpp @@ -191,8 +191,8 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS algo_inner_base { virtual std::string get_extra_info() const = 0; virtual thread_safety get_thread_safety() const = 0; virtual std::type_index get_type_index() const = 0; - virtual const void *get_void_ptr() const = 0; - virtual void *get_void_ptr() = 0; + virtual const void *get_ptr() const = 0; + virtual void *get_ptr() = 0; template void serialize(Archive &, unsigned) { @@ -346,11 +346,11 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS algo_inner final : algo_inner_base { return std::type_index(typeid(T)); } // Raw getters for the internal instance. - virtual const void *get_void_ptr() const override final + virtual const void *get_ptr() const override final { return &m_value; } - virtual void *get_void_ptr() override final + virtual void *get_ptr() override final { return &m_value; } @@ -691,7 +691,7 @@ class PAGMO_DLL_PUBLIC algorithm * * @return a pointer to the internal UDA. */ - const void *get_void_ptr() const; + const void *get_ptr() const; /// Get a mutable pointer to the UDA. /** @@ -718,7 +718,7 @@ class PAGMO_DLL_PUBLIC algorithm * * @return a pointer to the internal UDA. */ - void *get_void_ptr(); + void *get_ptr(); /// Save to archive. /** diff --git a/include/pagmo/bfe.hpp b/include/pagmo/bfe.hpp index 758164f12..13ecfd5a7 100644 --- a/include/pagmo/bfe.hpp +++ b/include/pagmo/bfe.hpp @@ -123,8 +123,8 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS bfe_inner_base { virtual std::string get_extra_info() const = 0; virtual thread_safety get_thread_safety() const = 0; virtual std::type_index get_type_index() const = 0; - virtual const void *get_void_ptr() const = 0; - virtual void *get_void_ptr() = 0; + virtual const void *get_ptr() const = 0; + virtual void *get_ptr() = 0; template void serialize(Archive &, unsigned) { @@ -202,11 +202,11 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS bfe_inner final : bfe_inner_base { return std::type_index(typeid(T)); } // Raw getters for the internal instance. - virtual const void *get_void_ptr() const override final + virtual const void *get_ptr() const override final { return &m_value; } - virtual void *get_void_ptr() override final + virtual void *get_ptr() override final { return &m_value; } @@ -340,10 +340,10 @@ class PAGMO_DLL_PUBLIC bfe std::type_index get_type_index() const; // Get a const pointer to the UDBFE. - const void *get_void_ptr() const; + const void *get_ptr() const; // Get a mutable pointer to the UDBFE. - void *get_void_ptr(); + void *get_ptr(); // Serialisation support. template diff --git a/include/pagmo/detail/typeid_name_extract.hpp b/include/pagmo/detail/typeid_name_extract.hpp index 3e6ca45c5..ae92d42ae 100644 --- a/include/pagmo/detail/typeid_name_extract.hpp +++ b/include/pagmo/detail/typeid_name_extract.hpp @@ -58,7 +58,7 @@ inline typename std::conditional::value, const T *, T *>::type } else { // The names match, cast to the correct type and return. return static_cast::value, const T *, T *>::type>( - class_inst.get_void_ptr()); + class_inst.get_ptr()); } } diff --git a/include/pagmo/island.hpp b/include/pagmo/island.hpp index 8f03cb127..90c78f214 100644 --- a/include/pagmo/island.hpp +++ b/include/pagmo/island.hpp @@ -152,8 +152,8 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS isl_inner_base { virtual std::string get_name() const = 0; virtual std::string get_extra_info() const = 0; virtual std::type_index get_type_index() const = 0; - virtual const void *get_void_ptr() const = 0; - virtual void *get_void_ptr() = 0; + virtual const void *get_ptr() const = 0; + virtual void *get_ptr() = 0; template void serialize(Archive &, unsigned) { @@ -216,11 +216,11 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS isl_inner final : isl_inner_base { return std::type_index(typeid(T)); } // Raw getters for the internal instance. - virtual const void *get_void_ptr() const override final + virtual const void *get_ptr() const override final { return &m_value; } - virtual void *get_void_ptr() override final + virtual void *get_ptr() override final { return &m_value; } @@ -1158,7 +1158,7 @@ class PAGMO_DLL_PUBLIC island * * @return a pointer to the internal UDI. */ - const void *get_void_ptr() const; + const void *get_ptr() const; /// Get a mutable pointer to the UDI. /** @@ -1185,7 +1185,7 @@ class PAGMO_DLL_PUBLIC island * * @return a pointer to the internal UDI. */ - void *get_void_ptr(); + void *get_ptr(); /// Save to archive. /** diff --git a/include/pagmo/problem.hpp b/include/pagmo/problem.hpp index 248b399d6..1415df3e5 100644 --- a/include/pagmo/problem.hpp +++ b/include/pagmo/problem.hpp @@ -543,8 +543,8 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS prob_inner_base { virtual std::string get_extra_info() const = 0; virtual thread_safety get_thread_safety() const = 0; virtual std::type_index get_type_index() const = 0; - virtual const void *get_void_ptr() const = 0; - virtual void *get_void_ptr() = 0; + virtual const void *get_ptr() const = 0; + virtual void *get_ptr() = 0; template void serialize(Archive &, unsigned) { @@ -921,11 +921,11 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS prob_inner final : prob_inner_base { return std::type_index(typeid(T)); } // Raw getters for the internal instance. - virtual const void *get_void_ptr() const override final + virtual const void *get_ptr() const override final { return &m_value; } - virtual void *get_void_ptr() override final + virtual void *get_ptr() override final { return &m_value; } @@ -1643,7 +1643,7 @@ class PAGMO_DLL_PUBLIC problem * * @return a pointer to the internal UDP. */ - const void *get_void_ptr() const; + const void *get_ptr() const; /// Get a mutable pointer to the UDP. /** @@ -1670,7 +1670,7 @@ class PAGMO_DLL_PUBLIC problem * * @return a pointer to the internal UDP. */ - void *get_void_ptr(); + void *get_ptr(); /// Save to archive. /** diff --git a/include/pagmo/r_policy.hpp b/include/pagmo/r_policy.hpp index d5afa743f..965ded66e 100644 --- a/include/pagmo/r_policy.hpp +++ b/include/pagmo/r_policy.hpp @@ -127,8 +127,8 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS r_pol_inner_base { virtual std::string get_name() const = 0; virtual std::string get_extra_info() const = 0; virtual std::type_index get_type_index() const = 0; - virtual const void *get_void_ptr() const = 0; - virtual void *get_void_ptr() = 0; + virtual const void *get_ptr() const = 0; + virtual void *get_ptr() = 0; template void serialize(Archive &, unsigned) { @@ -194,11 +194,11 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS r_pol_inner final : r_pol_inner_base { return std::type_index(typeid(T)); } // Raw getters for the internal instance. - virtual const void *get_void_ptr() const override final + virtual const void *get_ptr() const override final { return &m_value; } - virtual void *get_void_ptr() override final + virtual void *get_ptr() override final { return &m_value; } @@ -310,10 +310,10 @@ class PAGMO_DLL_PUBLIC r_policy std::type_index get_type_index() const; // Get a const pointer to the UDRP. - const void *get_void_ptr() const; + const void *get_ptr() const; // Get a mutable pointer to the UDRP. - void *get_void_ptr(); + void *get_ptr(); // Serialisation support. template diff --git a/include/pagmo/s_policy.hpp b/include/pagmo/s_policy.hpp index f833c8926..f82c857b5 100644 --- a/include/pagmo/s_policy.hpp +++ b/include/pagmo/s_policy.hpp @@ -127,8 +127,8 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS s_pol_inner_base { virtual std::string get_name() const = 0; virtual std::string get_extra_info() const = 0; virtual std::type_index get_type_index() const = 0; - virtual const void *get_void_ptr() const = 0; - virtual void *get_void_ptr() = 0; + virtual const void *get_ptr() const = 0; + virtual void *get_ptr() = 0; template void serialize(Archive &, unsigned) { @@ -194,11 +194,11 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS s_pol_inner final : s_pol_inner_base { return std::type_index(typeid(T)); } // Raw getters for the internal instance. - virtual const void *get_void_ptr() const override final + virtual const void *get_ptr() const override final { return &m_value; } - virtual void *get_void_ptr() override final + virtual void *get_ptr() override final { return &m_value; } @@ -310,10 +310,10 @@ class PAGMO_DLL_PUBLIC s_policy std::type_index get_type_index() const; // Get a const pointer to the UDSP. - const void *get_void_ptr() const; + const void *get_ptr() const; // Get a mutable pointer to the UDSP. - void *get_void_ptr(); + void *get_ptr(); // Serialisation support. template diff --git a/include/pagmo/topology.hpp b/include/pagmo/topology.hpp index 68cd422c5..2eb6bb3a3 100644 --- a/include/pagmo/topology.hpp +++ b/include/pagmo/topology.hpp @@ -176,8 +176,8 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS topo_inner_base { virtual void push_back() = 0; virtual bgl_graph_t to_bgl() const = 0; virtual std::type_index get_type_index() const = 0; - virtual const void *get_void_ptr() const = 0; - virtual void *get_void_ptr() = 0; + virtual const void *get_ptr() const = 0; + virtual void *get_ptr() = 0; template void serialize(Archive &, unsigned) { @@ -261,11 +261,11 @@ struct PAGMO_DLL_PUBLIC_INLINE_CLASS topo_inner final : topo_inner_base { return std::type_index(typeid(T)); } // Raw getters for the internal instance. - virtual const void *get_void_ptr() const override final + virtual const void *get_ptr() const override final { return &m_value; } - virtual void *get_void_ptr() override final + virtual void *get_ptr() override final { return &m_value; } @@ -386,10 +386,10 @@ class PAGMO_DLL_PUBLIC topology std::type_index get_type_index() const; // Get a const pointer to the UDT. - const void *get_void_ptr() const; + const void *get_ptr() const; // Get a mutable pointer to the UDT. - void *get_void_ptr(); + void *get_ptr(); // Serialization. template diff --git a/src/algorithm.cpp b/src/algorithm.cpp index 0b55018f9..18ca9255e 100644 --- a/src/algorithm.cpp +++ b/src/algorithm.cpp @@ -216,14 +216,14 @@ std::type_index algorithm::get_type_index() const return ptr()->get_type_index(); } -const void *algorithm::get_void_ptr() const +const void *algorithm::get_ptr() const { - return ptr()->get_void_ptr(); + return ptr()->get_ptr(); } -void *algorithm::get_void_ptr() +void *algorithm::get_ptr() { - return ptr()->get_void_ptr(); + return ptr()->get_ptr(); } /// Streaming operator for pagmo::algorithm diff --git a/src/bfe.cpp b/src/bfe.cpp index 8ec257d5d..aac533a80 100644 --- a/src/bfe.cpp +++ b/src/bfe.cpp @@ -126,14 +126,14 @@ std::type_index bfe::get_type_index() const return ptr()->get_type_index(); } -const void *bfe::get_void_ptr() const +const void *bfe::get_ptr() const { - return ptr()->get_void_ptr(); + return ptr()->get_ptr(); } -void *bfe::get_void_ptr() +void *bfe::get_ptr() { - return ptr()->get_void_ptr(); + return ptr()->get_ptr(); } #if !defined(PAGMO_DOXYGEN_INVOKED) diff --git a/src/island.cpp b/src/island.cpp index 9ab84ffe8..0c24f2308 100644 --- a/src/island.cpp +++ b/src/island.cpp @@ -882,14 +882,14 @@ std::type_index island::get_type_index() const return m_ptr->isl_ptr->get_type_index(); } -const void *island::get_void_ptr() const +const void *island::get_ptr() const { - return m_ptr->isl_ptr->get_void_ptr(); + return m_ptr->isl_ptr->get_ptr(); } -void *island::get_void_ptr() +void *island::get_ptr() { - return m_ptr->isl_ptr->get_void_ptr(); + return m_ptr->isl_ptr->get_ptr(); } #if !defined(PAGMO_DOXYGEN_INVOKED) diff --git a/src/problem.cpp b/src/problem.cpp index 52b241cd8..7284e9e9f 100644 --- a/src/problem.cpp +++ b/src/problem.cpp @@ -760,14 +760,14 @@ std::type_index problem::get_type_index() const return ptr()->get_type_index(); } -const void *problem::get_void_ptr() const +const void *problem::get_ptr() const { - return ptr()->get_void_ptr(); + return ptr()->get_ptr(); } -void *problem::get_void_ptr() +void *problem::get_ptr() { - return ptr()->get_void_ptr(); + return ptr()->get_ptr(); } /// Streaming operator diff --git a/src/r_policy.cpp b/src/r_policy.cpp index 86275d007..7045c75db 100644 --- a/src/r_policy.cpp +++ b/src/r_policy.cpp @@ -244,14 +244,14 @@ std::type_index r_policy::get_type_index() const return ptr()->get_type_index(); } -const void *r_policy::get_void_ptr() const +const void *r_policy::get_ptr() const { - return ptr()->get_void_ptr(); + return ptr()->get_ptr(); } -void *r_policy::get_void_ptr() +void *r_policy::get_ptr() { - return ptr()->get_void_ptr(); + return ptr()->get_ptr(); } #if !defined(PAGMO_DOXYGEN_INVOKED) diff --git a/src/s_policy.cpp b/src/s_policy.cpp index 0eaeb43f4..8285b322f 100644 --- a/src/s_policy.cpp +++ b/src/s_policy.cpp @@ -227,14 +227,14 @@ std::type_index s_policy::get_type_index() const return ptr()->get_type_index(); } -const void *s_policy::get_void_ptr() const +const void *s_policy::get_ptr() const { - return ptr()->get_void_ptr(); + return ptr()->get_ptr(); } -void *s_policy::get_void_ptr() +void *s_policy::get_ptr() { - return ptr()->get_void_ptr(); + return ptr()->get_ptr(); } #if !defined(PAGMO_DOXYGEN_INVOKED) diff --git a/src/topology.cpp b/src/topology.cpp index 8af15fb53..fdfbf2341 100644 --- a/src/topology.cpp +++ b/src/topology.cpp @@ -165,14 +165,14 @@ std::type_index topology::get_type_index() const return ptr()->get_type_index(); } -const void *topology::get_void_ptr() const +const void *topology::get_ptr() const { - return ptr()->get_void_ptr(); + return ptr()->get_ptr(); } -void *topology::get_void_ptr() +void *topology::get_ptr() { - return ptr()->get_void_ptr(); + return ptr()->get_ptr(); } #if !defined(PAGMO_DOXYGEN_INVOKED) diff --git a/tests/algorithm.cpp b/tests/algorithm.cpp index fa43107f7..e9b12eda5 100644 --- a/tests/algorithm.cpp +++ b/tests/algorithm.cpp @@ -510,16 +510,15 @@ BOOST_AUTO_TEST_CASE(type_index) BOOST_CHECK(p0.get_type_index() == std::type_index(typeid(al_01))); } -BOOST_AUTO_TEST_CASE(get_void_ptr) +BOOST_AUTO_TEST_CASE(get_ptr) { algorithm p0; - BOOST_CHECK(p0.get_void_ptr() == p0.extract()); - BOOST_CHECK(static_cast(p0).get_void_ptr() + BOOST_CHECK(p0.get_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_ptr() == static_cast(p0).extract()); p0 = algorithm{al_01{}}; - BOOST_CHECK(p0.get_void_ptr() == p0.extract()); - BOOST_CHECK(static_cast(p0).get_void_ptr() - == static_cast(p0).extract()); + BOOST_CHECK(p0.get_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_ptr() == static_cast(p0).extract()); } BOOST_AUTO_TEST_CASE(stream_operator) diff --git a/tests/bfe.cpp b/tests/bfe.cpp index 7a08808ee..a788e246c 100644 --- a/tests/bfe.cpp +++ b/tests/bfe.cpp @@ -521,12 +521,12 @@ BOOST_AUTO_TEST_CASE(type_index) BOOST_CHECK(p0.get_type_index() == std::type_index(typeid(udbfe1))); } -BOOST_AUTO_TEST_CASE(get_void_ptr) +BOOST_AUTO_TEST_CASE(get_ptr) { bfe p0; - BOOST_CHECK(p0.get_void_ptr() == p0.extract()); - BOOST_CHECK(static_cast(p0).get_void_ptr() == static_cast(p0).extract()); + BOOST_CHECK(p0.get_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_ptr() == static_cast(p0).extract()); p0 = bfe{udbfe1{}}; - BOOST_CHECK(p0.get_void_ptr() == p0.extract()); - BOOST_CHECK(static_cast(p0).get_void_ptr() == static_cast(p0).extract()); + BOOST_CHECK(p0.get_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_ptr() == static_cast(p0).extract()); } diff --git a/tests/island.cpp b/tests/island.cpp index b1a7b3f16..0b1712fd0 100644 --- a/tests/island.cpp +++ b/tests/island.cpp @@ -652,13 +652,12 @@ BOOST_AUTO_TEST_CASE(type_index) BOOST_CHECK(p0.get_type_index() == std::type_index(typeid(udi_01a))); } -BOOST_AUTO_TEST_CASE(get_void_ptr) +BOOST_AUTO_TEST_CASE(get_ptr) { island p0; - BOOST_CHECK(p0.get_void_ptr() == p0.extract()); - BOOST_CHECK(static_cast(p0).get_void_ptr() - == static_cast(p0).extract()); + BOOST_CHECK(p0.get_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_ptr() == static_cast(p0).extract()); p0 = island{udi_01a{}, de{}, population{rosenbrock{}, 25}}; - BOOST_CHECK(p0.get_void_ptr() == p0.extract()); - BOOST_CHECK(static_cast(p0).get_void_ptr() == static_cast(p0).extract()); + BOOST_CHECK(p0.get_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_ptr() == static_cast(p0).extract()); } diff --git a/tests/problem.cpp b/tests/problem.cpp index 90e0a7455..d1a761e5d 100644 --- a/tests/problem.cpp +++ b/tests/problem.cpp @@ -1605,14 +1605,13 @@ BOOST_AUTO_TEST_CASE(type_index) BOOST_CHECK(p0.get_type_index() == std::type_index(typeid(grad_p_override))); } -BOOST_AUTO_TEST_CASE(get_void_ptr) +BOOST_AUTO_TEST_CASE(get_ptr) { problem p0; - BOOST_CHECK(p0.get_void_ptr() == p0.extract()); - BOOST_CHECK(static_cast(p0).get_void_ptr() - == static_cast(p0).extract()); + BOOST_CHECK(p0.get_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_ptr() == static_cast(p0).extract()); p0 = problem{grad_p_override{}}; - BOOST_CHECK(p0.get_void_ptr() == p0.extract()); - BOOST_CHECK(static_cast(p0).get_void_ptr() + BOOST_CHECK(p0.get_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_ptr() == static_cast(p0).extract()); } diff --git a/tests/r_policy.cpp b/tests/r_policy.cpp index c6d1d2765..ad73496ca 100644 --- a/tests/r_policy.cpp +++ b/tests/r_policy.cpp @@ -601,13 +601,13 @@ BOOST_AUTO_TEST_CASE(type_index) BOOST_CHECK(p0.get_type_index() == std::type_index(typeid(udrp1))); } -BOOST_AUTO_TEST_CASE(get_void_ptr) +BOOST_AUTO_TEST_CASE(get_ptr) { r_policy p0; - BOOST_CHECK(p0.get_void_ptr() == p0.extract()); - BOOST_CHECK(static_cast(p0).get_void_ptr() + BOOST_CHECK(p0.get_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_ptr() == static_cast(p0).extract()); p0 = r_policy{udrp1{}}; - BOOST_CHECK(p0.get_void_ptr() == p0.extract()); - BOOST_CHECK(static_cast(p0).get_void_ptr() == static_cast(p0).extract()); + BOOST_CHECK(p0.get_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_ptr() == static_cast(p0).extract()); } diff --git a/tests/s_policy.cpp b/tests/s_policy.cpp index d656add47..24dbb436f 100644 --- a/tests/s_policy.cpp +++ b/tests/s_policy.cpp @@ -562,13 +562,13 @@ BOOST_AUTO_TEST_CASE(type_index) BOOST_CHECK(p0.get_type_index() == std::type_index(typeid(udsp1))); } -BOOST_AUTO_TEST_CASE(get_void_ptr) +BOOST_AUTO_TEST_CASE(get_ptr) { s_policy p0; - BOOST_CHECK(p0.get_void_ptr() == p0.extract()); - BOOST_CHECK(static_cast(p0).get_void_ptr() + BOOST_CHECK(p0.get_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_ptr() == static_cast(p0).extract()); p0 = s_policy{udsp1{}}; - BOOST_CHECK(p0.get_void_ptr() == p0.extract()); - BOOST_CHECK(static_cast(p0).get_void_ptr() == static_cast(p0).extract()); + BOOST_CHECK(p0.get_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_ptr() == static_cast(p0).extract()); } diff --git a/tests/topology.cpp b/tests/topology.cpp index 4f1126832..075bb3137 100644 --- a/tests/topology.cpp +++ b/tests/topology.cpp @@ -380,14 +380,13 @@ BOOST_AUTO_TEST_CASE(type_index) BOOST_CHECK(p0.get_type_index() == std::type_index(typeid(udt00a))); } -BOOST_AUTO_TEST_CASE(get_void_ptr) +BOOST_AUTO_TEST_CASE(get_ptr) { topology p0; - BOOST_CHECK(p0.get_void_ptr() == p0.extract()); - BOOST_CHECK(static_cast(p0).get_void_ptr() + BOOST_CHECK(p0.get_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_ptr() == static_cast(p0).extract()); p0 = topology{udt00a{}}; - BOOST_CHECK(p0.get_void_ptr() == p0.extract()); - BOOST_CHECK(static_cast(p0).get_void_ptr() - == static_cast(p0).extract()); + BOOST_CHECK(p0.get_ptr() == p0.extract()); + BOOST_CHECK(static_cast(p0).get_ptr() == static_cast(p0).extract()); } From 47472a03ed42502ea856476fecf072ed6ec3b7c1 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 28 Mar 2020 22:48:45 +0100 Subject: [PATCH 23/30] Update changelog. --- doc/sphinx/changelog.rst | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/doc/sphinx/changelog.rst b/doc/sphinx/changelog.rst index a16b936ca..4a8f99877 100644 --- a/doc/sphinx/changelog.rst +++ b/doc/sphinx/changelog.rst @@ -9,6 +9,13 @@ Changelog New ~~~ +- The type-erased wrappers now have additional member functions + to interact at runtime with the contained user-defined objects. + Specifically, it is now possible to fetch ``void`` pointers to the + user-defined objects without knowing their type, and to query + at runtime the ``std::type_index`` of the user-defined objects + (`#410 `__). + - Add a :cpp:func:`pagmo::base_bgl_topology::get_edge_weight()` function to fetch the weight of an edge in a BGL topology (`#407 `__). @@ -23,8 +30,12 @@ New Fix ~~~ +- Build fixes for recent CMake versions + (`#410 `__). + - Various doc fixes - (`#405 `__). + (`#410 `__, + `#405 `__). 2.14.0 (2020-03-04) ------------------- From 8b2f48dfc95422904f1477e335e3a1a2e0f24be3 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 28 Mar 2020 22:52:15 +0100 Subject: [PATCH 24/30] Try another circleci build for the docs. --- .circleci/config.yml | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 06e9d7032..97cb9cc09 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -17,30 +17,38 @@ jobs: - run: name: Build and test command: bash ./tools/circleci_focal_gcc9_asan.sh - focal_clang9: + focal_gcc9_docs: docker: - image: circleci/buildpack-deps:focal steps: - checkout - run: name: Build and test - command: bash ./tools/circleci_focal_clang9.sh - bionic_clang6_release: + command: bash ./tools/circleci_focal_gcc9_docs.sh + focal_clang9: docker: - - image: circleci/buildpack-deps:bionic + - image: circleci/buildpack-deps:focal steps: - checkout - run: name: Build and test - command: bash ./tools/circleci_bionic_clang6_release.sh - bionic_gcc7_conda_docs: + command: bash ./tools/circleci_focal_clang9.sh + bionic_clang6_release: docker: - image: circleci/buildpack-deps:bionic steps: - checkout - run: name: Build and test - command: bash ./tools/circleci_bionic_gcc7_conda_docs.sh + command: bash ./tools/circleci_bionic_clang6_release.sh + # bionic_gcc7_conda_docs: + # docker: + # - image: circleci/buildpack-deps:bionic + # steps: + # - checkout + # - run: + # name: Build and test + # command: bash ./tools/circleci_bionic_gcc7_conda_docs.sh workflows: version: 2 @@ -50,4 +58,5 @@ workflows: - focal_gcc9_asan - focal_clang9 - bionic_clang6_release - - bionic_gcc7_conda_docs + # - bionic_gcc7_conda_docs + - focal_gcc9_docs From 19bfab19b65b325837dd55f225fb6c7e8dd25fe8 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 28 Mar 2020 22:52:35 +0100 Subject: [PATCH 25/30] Missing file. --- tools/circleci_focal_gcc9_docs.sh | 93 +++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 tools/circleci_focal_gcc9_docs.sh diff --git a/tools/circleci_focal_gcc9_docs.sh b/tools/circleci_focal_gcc9_docs.sh new file mode 100644 index 000000000..c6a22a06f --- /dev/null +++ b/tools/circleci_focal_gcc9_docs.sh @@ -0,0 +1,93 @@ +#!/usr/bin/env bash + +# Echo each command +set -x + +# Exit on error. +set -e + +# Core deps. +sudo apt-get install build-essential wget doxygen graphviz + +# Install conda+deps. +wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh +export deps_dir=$HOME/local +export PATH="$HOME/miniconda/bin:$PATH" +bash miniconda.sh -b -p $HOME/miniconda +conda config --add channels conda-forge --force +conda_pkgs="cmake eigen nlopt ipopt boost-cpp tbb tbb-devel python=3.7 sphinx sphinx_rtd_theme breathe" +conda create -q -p $deps_dir -y +source activate $deps_dir +conda install $conda_pkgs -y + +# Create the build dir and cd into it. +mkdir build +cd build + +# GCC build. +cmake ../ -DCMAKE_CXX_STANDARD=17 -DCMAKE_BUILD_TYPE=Release -DPAGMO_BUILD_TESTS=yes -DPAGMO_WITH_EIGEN3=yes -DPAGMO_WITH_NLOPT=yes -DPAGMO_WITH_IPOPT=yes +make -j2 VERBOSE=1 +ctest -V + +# Build the documentation. + +# Doxygen. +cd ../doc/doxygen +export DOXYGEN_OUTPUT=`doxygen 2>&1 >/dev/null`; +if [[ "${DOXYGEN_OUTPUT}" != "" ]]; then + echo "Doxygen encountered some problem:"; + echo "${DOXYGEN_OUTPUT}"; + exit 1; +fi +echo "Doxygen ran successfully"; + +# Copy the images into the xml output dir (this is needed by sphinx). +cp images/* xml/; +cd ../sphinx/; +export SPHINX_OUTPUT=`make html linkcheck 2>&1 | grep -v "Duplicate declaration" | grep -v "is deprecated" >/dev/null`; +if [[ "${SPHINX_OUTPUT}" != "" ]]; then + echo "Sphinx encountered some problem:"; + echo "${SPHINX_OUTPUT}"; + exit 1; +fi +echo "Sphinx ran successfully"; + +if [[ ! -z "${CI_PULL_REQUEST}" ]]; then + echo "Testing a pull request, the generated documentation will not be uploaded."; + exit 0; +fi + +if [[ "${CIRCLE_BRANCH}" != "master" ]]; then + echo "Branch is not master, the generated documentation will not be uploaded."; + exit 0; +fi + +# Check out the gh_pages branch in a separate dir. +cd ../.. +git config --global push.default simple +git config --global user.name "CircleCI" +git config --global user.email "bluescarni@gmail.com" +set +x +git clone "https://${GH_TOKEN}@github.com/esa/pagmo2.git" pagmo2_gh_pages -q +set -x +cd pagmo2_gh_pages +git checkout -b gh-pages --track origin/gh-pages; +git rm -fr *; +mv ../doc/sphinx/_build/html/* .; +git add *; +# We assume here that a failure in commit means that there's nothing +# to commit. +git commit -m "Update Sphinx documentation, commit ${CIRCLE_SHA1} [skip ci]." || exit 0 +PUSH_COUNTER=0 +until git push -q +do + git pull -q + PUSH_COUNTER=$((PUSH_COUNTER + 1)) + if [ "$PUSH_COUNTER" -gt 3 ]; then + echo "Push failed, aborting."; + exit 1; + fi +done + +set +e +set +x From 66deaa6c312da302bfb26dbd94cdb25218af06dc Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 28 Mar 2020 23:04:24 +0100 Subject: [PATCH 26/30] Cleanup. --- .circleci/config.yml | 9 --- tools/circleci_bionic_gcc7_conda_docs.sh | 93 ------------------------ 2 files changed, 102 deletions(-) delete mode 100644 tools/circleci_bionic_gcc7_conda_docs.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index 97cb9cc09..95f298019 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -41,14 +41,6 @@ jobs: - run: name: Build and test command: bash ./tools/circleci_bionic_clang6_release.sh - # bionic_gcc7_conda_docs: - # docker: - # - image: circleci/buildpack-deps:bionic - # steps: - # - checkout - # - run: - # name: Build and test - # command: bash ./tools/circleci_bionic_gcc7_conda_docs.sh workflows: version: 2 @@ -58,5 +50,4 @@ workflows: - focal_gcc9_asan - focal_clang9 - bionic_clang6_release - # - bionic_gcc7_conda_docs - focal_gcc9_docs diff --git a/tools/circleci_bionic_gcc7_conda_docs.sh b/tools/circleci_bionic_gcc7_conda_docs.sh deleted file mode 100644 index c475f4735..000000000 --- a/tools/circleci_bionic_gcc7_conda_docs.sh +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/env bash - -# Echo each command -set -x - -# Exit on error. -set -e - -# Core deps. -sudo apt-get install build-essential wget - -# Install conda+deps. -wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh -export deps_dir=$HOME/local -export PATH="$HOME/miniconda/bin:$PATH" -bash miniconda.sh -b -p $HOME/miniconda -conda config --add channels conda-forge --force -conda_pkgs="cmake eigen nlopt ipopt boost-cpp tbb tbb-devel python=3.7 sphinx sphinx_rtd_theme breathe doxygen graphviz" -conda create -q -p $deps_dir -y -source activate $deps_dir -conda install $conda_pkgs -y - -# Create the build dir and cd into it. -mkdir build -cd build - -# GCC build. -cmake ../ -DCMAKE_CXX_STANDARD=17 -DCMAKE_BUILD_TYPE=Release -DPAGMO_BUILD_TESTS=yes -DPAGMO_WITH_EIGEN3=yes -DPAGMO_WITH_NLOPT=yes -DPAGMO_WITH_IPOPT=yes -make -j2 VERBOSE=1 -ctest -V - -# Build the documentation. - -# Doxygen. -cd ../doc/doxygen -export DOXYGEN_OUTPUT=`doxygen 2>&1 >/dev/null`; -if [[ "${DOXYGEN_OUTPUT}" != "" ]]; then - echo "Doxygen encountered some problem:"; - echo "${DOXYGEN_OUTPUT}"; - exit 1; -fi -echo "Doxygen ran successfully"; - -# Copy the images into the xml output dir (this is needed by sphinx). -cp images/* xml/; -cd ../sphinx/; -export SPHINX_OUTPUT=`make html linkcheck 2>&1 | grep -v "Duplicate declaration" | grep -v "is deprecated" >/dev/null`; -if [[ "${SPHINX_OUTPUT}" != "" ]]; then - echo "Sphinx encountered some problem:"; - echo "${SPHINX_OUTPUT}"; - exit 1; -fi -echo "Sphinx ran successfully"; - -if [[ ! -z "${CI_PULL_REQUEST}" ]]; then - echo "Testing a pull request, the generated documentation will not be uploaded."; - exit 0; -fi - -if [[ "${CIRCLE_BRANCH}" != "master" ]]; then - echo "Branch is not master, the generated documentation will not be uploaded."; - exit 0; -fi - -# Check out the gh_pages branch in a separate dir. -cd ../.. -git config --global push.default simple -git config --global user.name "CircleCI" -git config --global user.email "bluescarni@gmail.com" -set +x -git clone "https://${GH_TOKEN}@github.com/esa/pagmo2.git" pagmo2_gh_pages -q -set -x -cd pagmo2_gh_pages -git checkout -b gh-pages --track origin/gh-pages; -git rm -fr *; -mv ../doc/sphinx/_build/html/* .; -git add *; -# We assume here that a failure in commit means that there's nothing -# to commit. -git commit -m "Update Sphinx documentation, commit ${CIRCLE_SHA1} [skip ci]." || exit 0 -PUSH_COUNTER=0 -until git push -q -do - git pull -q - PUSH_COUNTER=$((PUSH_COUNTER + 1)) - if [ "$PUSH_COUNTER" -gt 3 ]; then - echo "Push failed, aborting."; - exit 1; - fi -done - -set +e -set +x From 780a12f655320843f238fefc42dd4c5d9462e4df Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 28 Mar 2020 23:15:44 +0100 Subject: [PATCH 27/30] Last minute addition. --- doc/sphinx/changelog.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/sphinx/changelog.rst b/doc/sphinx/changelog.rst index 4a8f99877..c3532fd24 100644 --- a/doc/sphinx/changelog.rst +++ b/doc/sphinx/changelog.rst @@ -30,6 +30,13 @@ New Fix ~~~ +- Introduce a workaround for an issue present on some + compiler/standard library combinations, where + the ``dynamic_cast`` used in the ``extract()`` + implementations would fail when crossing the boundaries + between ``dlopen()``-ed libraries + (`#410 `__). + - Build fixes for recent CMake versions (`#410 `__). From e17657f67f7dd46e3ae14bad19e39bf7d33411b4 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 28 Mar 2020 23:17:52 +0100 Subject: [PATCH 28/30] Ditto. --- doc/sphinx/changelog.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/sphinx/changelog.rst b/doc/sphinx/changelog.rst index c3532fd24..d37dcd251 100644 --- a/doc/sphinx/changelog.rst +++ b/doc/sphinx/changelog.rst @@ -16,6 +16,10 @@ New at runtime the ``std::type_index`` of the user-defined objects (`#410 `__). +- The default ``get_name()`` implementations for the type-erased + wrappers now return the demangled C++ name on most platforms + (`#410 `__). + - Add a :cpp:func:`pagmo::base_bgl_topology::get_edge_weight()` function to fetch the weight of an edge in a BGL topology (`#407 `__). From a786ce21d255416777554bd3b3b80d27de44459b Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 28 Mar 2020 23:36:55 +0100 Subject: [PATCH 29/30] Fix the alternative extrac() implementation when the type is const qualified. --- include/pagmo/detail/typeid_name_extract.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/pagmo/detail/typeid_name_extract.hpp b/include/pagmo/detail/typeid_name_extract.hpp index ae92d42ae..e50edfb74 100644 --- a/include/pagmo/detail/typeid_name_extract.hpp +++ b/include/pagmo/detail/typeid_name_extract.hpp @@ -33,6 +33,8 @@ see https://www.gnu.org/licenses/. */ #include #include +#include + namespace pagmo { @@ -52,6 +54,13 @@ namespace detail template inline typename std::conditional::value, const T *, T *>::type typeid_name_extract(C &class_inst) { + // NOTE: typeid() strips away both reference and cv qualifiers. Thus, + // if T is cv-qualified or a reference type, return nullptr pre-empitvely + // (in any case, extraction cannot be successful in such cases). + if (!std::is_same>::value || std::is_reference::value) { + return nullptr; + } + if (std::strcmp(class_inst.get_type_index().name(), typeid(T).name())) { // The names differ, return null. return nullptr; From fdb8b4bd77996643fa6ba357c5f0783ce7d8114f Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sun, 29 Mar 2020 15:28:36 +0200 Subject: [PATCH 30/30] Small doc addition. --- doc/sphinx/install.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/sphinx/install.rst b/doc/sphinx/install.rst index 17bb8f781..e3f4c15a0 100644 --- a/doc/sphinx/install.rst +++ b/doc/sphinx/install.rst @@ -60,6 +60,7 @@ to the channels, and then we can immediately install pagmo: .. code-block:: console $ conda config --add channels conda-forge + $ conda config --set channel_priority strict $ conda install pagmo pagmo-devel The conda packages for pagmo are maintained by the core development team,