copyable.hpp 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. /* Copyright 2024 Joaquin M Lopez Munoz.
  2. * Distributed under the Boost Software License, Version 1.0.
  3. * (See accompanying file LICENSE_1_0.txt or copy at
  4. * http://www.boost.org/LICENSE_1_0.txt)
  5. *
  6. * See http://www.boost.org/libs/poly_collection for library home page.
  7. */
  8. #ifndef BOOST_POLY_COLLECTION_DETAIL_COPYABLE_HPP
  9. #define BOOST_POLY_COLLECTION_DETAIL_COPYABLE_HPP
  10. #if defined(_MSC_VER)
  11. #pragma once
  12. #endif
  13. #include <functional>
  14. #include <type_traits>
  15. namespace boost{
  16. namespace poly_collection{
  17. namespace detail{
  18. /* wraps T if it is not copyable */
  19. template<typename T,typename=void>
  20. struct copyable_impl{using type=T;};
  21. template<typename T>
  22. struct reference_wrapper
  23. {
  24. reference_wrapper(T& x):p{&x}{}
  25. operator T&()const noexcept{return *p;}
  26. T* p;
  27. };
  28. template<typename T>
  29. struct copyable_impl<
  30. T,
  31. typename std::enable_if<!std::is_copy_constructible<T>::value>::type
  32. >
  33. {using type=reference_wrapper<const T>;};
  34. template<typename T>
  35. using copyable=typename copyable_impl<T>::type;
  36. template<typename T>
  37. copyable<T> make_copyable(const T& x){return x;}
  38. } /* namespace poly_collection::detail */
  39. } /* namespace poly_collection */
  40. } /* namespace boost */
  41. #endif