From f599bc06b2e7d351b69b1b751c7f97933c205b15 Mon Sep 17 00:00:00 2001 From: kleeman Date: Thu, 7 Mar 2019 13:08:27 -0800 Subject: [PATCH 1/2] Refactor (and improve) traits --- albatross/cereal/traits.h | 71 ++++ albatross/core/traits.h | 298 ++++++---------- albatross/covariance_functions/call_trace.h | 4 +- .../covariance_function.h | 52 +-- albatross/covariance_functions/noise.h | 7 +- albatross/covariance_functions/polynomials.h | 17 +- albatross/covariance_functions/radial.h | 25 +- .../covariance_functions/scaling_function.h | 20 +- albatross/covariance_functions/traits.h | 133 ++++++++ tests/test_traits_cereal.cc | 83 +++++ tests/test_traits_core.cc | 317 ++++++++++++++++++ ...cc => test_traits_covariance_functions.cc} | 91 +---- 12 files changed, 776 insertions(+), 342 deletions(-) create mode 100644 albatross/cereal/traits.h create mode 100644 albatross/covariance_functions/traits.h create mode 100644 tests/test_traits_cereal.cc create mode 100644 tests/test_traits_core.cc rename tests/{test_traits.cc => test_traits_covariance_functions.cc} (65%) diff --git a/albatross/cereal/traits.h b/albatross/cereal/traits.h new file mode 100644 index 00000000..ed86730f --- /dev/null +++ b/albatross/cereal/traits.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2018 Swift Navigation Inc. + * Contact: Swift Navigation + * + * This source is subject to the license found in the file 'LICENSE' which must + * be distributed together with this source. All other rights reserved. + * + * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, + * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef ALBATROSS_CEREAL_TRAITS_H +#define ALBATROSS_CEREAL_TRAITS_H + +#include "cereal/details/traits.hpp" + +namespace albatross { + +/* + * This little trick was borrowed from cereal, you an think of it as + * a function that will always return false ... but that doesn't + * get resolved until template instantiation, which when combined + * with a static assert let's you include a static assert that + * only triggers with a particular template parameter is used. + */ +template struct delay_static_assert : std::false_type {}; + +/* + * The following helper functions let you inspect a type and cereal Archive + * and determine if the type has a valid serialization method for that Archive + * type. + */ +template class valid_output_serializer { + template + static typename std::enable_if< + 1 == cereal::traits::detail::count_output_serializers::value, + std::true_type>::type + test(int); + template static std::false_type test(...); + +public: + static constexpr bool value = decltype(test(0))::value; +}; + +template class valid_input_serializer { + template + static typename std::enable_if< + 1 == cereal::traits::detail::count_input_serializers::value, + std::true_type>::type + test(int); + template static std::false_type test(...); + +public: + static constexpr bool value = decltype(test(0))::value; +}; + +template class valid_in_out_serializer { + template + static typename std::enable_if::value && + valid_output_serializer::value, + std::true_type>::type + test(int); + template static std::false_type test(...); + +public: + static constexpr bool value = decltype(test(0))::value; +}; +} + +#endif diff --git a/albatross/core/traits.h b/albatross/core/traits.h index 92884a44..2d1a0e5e 100644 --- a/albatross/core/traits.h +++ b/albatross/core/traits.h @@ -13,268 +13,170 @@ #ifndef ALBATROSS_CORE_TRAITS_H #define ALBATROSS_CORE_TRAITS_H -#include "cereal/details/traits.hpp" -#include "core/declarations.h" -#include - namespace albatross { /* - * This little trick was borrowed from cereal, you an think of it as - * a function that will always return false ... but that doesn't - * get resolved until template instantiation, which when combined - * with a static assert let's you include a static assert that - * only triggers with a particular template parameter is used. + * Checks if a class type is complete by using sizeof. + * + * https://stackoverflow.com/questions/25796126/static-assert-that-template-typename-t-is-not-complete */ -template struct delay_static_assert : std::false_type {}; +template class is_complete { + template + static std::true_type test(int); + template static std::false_type test(...); -/* - * In CovarianceFunction we frequently inspect for definitions of - * call_impl_ which MUST be defined for const references to objects - * (so that repeated covariance matrix evaluations return the same thing - * and so the computations are not repeatedly copying.) - * This type conversion utility will turn a type `T` into `const T&` - */ -template struct call_impl_arg_type { - typedef - typename std::add_lvalue_reference::type>::type - type; +public: + static constexpr bool value = decltype(test(0))::value; }; /* - * This determines whether or not a class has a method defined for, - * `operator() (const X &x, const Y &y, const Z &z, ...)` - * The result of the inspection gets stored in the member `value`. + * This determines whether or not a class, T, has a method, + * `std::string T.name() const` */ -template class has_call_operator { +template class has_name { + template ().name())> + static + typename std::enable_if::value, std::true_type>::type + test(int); - template ()( - std::declval::type>()...))> - static std::true_type test(C *); - template static std::false_type test(...); + template static std::false_type test(...); public: static constexpr bool value = decltype(test(0))::value; }; /* - * This determines whether or not a class has a method defined for, - * `double call_impl_(const X &x, const Y &y, const Z &z, ...)` - * The result of the inspection gets stored in the member `value`. + * Like std::is_base_of except compares the first template parameter. Ie, + * + * first_template_param_is_base_of, C>::value == is_base_of::value */ -template class has_valid_call_impl { +template +struct first_template_param_is_base_of : public std::false_type {}; - template - static typename std::is_same< - decltype(std::declval().call_impl_( - std::declval::type>()...)), - double>::type - test(C *); - template static std::false_type test(...); +template