1 /* 2 Copyright (C) 2012 - 2018 by Mark de Wever <koraq@xs4all.nl> 3 Part of the Battle for Wesnoth Project https://www.wesnoth.org/ 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY. 11 12 See the COPYING file for more details. 13 */ 14 15 #pragma once 16 17 #include "utils/type_trait_aliases.hpp" 18 19 #include <type_traits> 20 21 namespace utils 22 { 23 /** 24 * Helper struct to clone the constness of one type to another. 25 * 26 * @warning It seems @c *this in a const member function is not a const object, 27 * use @c this, which is a pointer to a const object. 28 * 29 * @tparam D The destination type, it should have no 30 * cv-qualifier and not be a pointer or 31 * reference. 32 * @tparam S The source type, this type may be a pointer 33 * or reference and obviously is allowed to have 34 * a cv-qualifier, although @c volatile has no 35 * effect. 36 */ 37 template<typename D, typename S> 38 struct const_clone 39 { 40 static const bool is_source_const = 41 std::is_const< 42 utils::remove_pointer_t< 43 utils::remove_reference_t<S> 44 > 45 >::value; 46 47 /** The destination type, possibly const qualified. */ 48 using type = 49 utils::conditional_t<is_source_const, const D, D>; 50 51 /** A reference to the destination type, possibly const qualified. */ 52 using reference = 53 utils::conditional_t<is_source_const, const D&, D&>; 54 55 /** A pointer to the destination type, possibly const qualified. */ 56 using pointer = 57 utils::conditional_t<is_source_const, const D*, D*>; 58 }; 59 60 template<typename D, typename S> 61 using const_clone_t = typename const_clone<D, S>::type; 62 63 template<typename D, typename S> 64 using const_clone_ref = typename const_clone<D, S>::reference; 65 66 template<typename D, typename S> 67 using const_clone_ptr = typename const_clone<D, S>::pointer; 68 69 } // namespace utils 70