constexpr.hpp 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. ///////////////////////////////////////////////////////////////
  2. // Copyright 2019 John Maddock. Distributed under the Boost
  3. // Software License, Version 1.0. (See accompanying file
  4. // LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
  5. #ifndef BOOST_MP_DETAIL_CONSTEXPR_HPP
  6. #define BOOST_MP_DETAIL_CONSTEXPR_HPP
  7. #include <cstring>
  8. #include <boost/multiprecision/detail/standalone_config.hpp>
  9. namespace boost {
  10. namespace multiprecision {
  11. namespace std_constexpr {
  12. template <class T>
  13. inline BOOST_CXX14_CONSTEXPR void swap(T& a, T& b)
  14. {
  15. T t(a);
  16. a = b;
  17. b = t;
  18. }
  19. template <class InputIterator, class OutputIterator>
  20. inline BOOST_CXX14_CONSTEXPR OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result)
  21. {
  22. //
  23. // There are 3 branches here, only one of which is selected at compile time:
  24. //
  25. #ifndef BOOST_MP_NO_CONSTEXPR_DETECTION
  26. if (BOOST_MP_IS_CONST_EVALUATED(*first))
  27. {
  28. // constexpr safe code, never generates runtime code:
  29. while (first != last)
  30. {
  31. *result = *first;
  32. ++first;
  33. ++result;
  34. }
  35. return result;
  36. }
  37. else
  38. #endif
  39. {
  40. #ifndef BOOST_NO_CXX17_IF_CONSTEXPR
  41. if constexpr (std::is_pointer<InputIterator>::value && std::is_pointer<OutputIterator>::value && std::is_trivially_copyable<typename std::remove_reference<decltype(*first)>::type>::value)
  42. {
  43. // The normal runtime branch:
  44. std::memcpy(result, first, static_cast<std::size_t>(static_cast<std::size_t>(last - first) * sizeof(*first)));
  45. return result + (last - first);
  46. }
  47. else
  48. #endif
  49. {
  50. // Alternate runtime branch:
  51. while (first != last)
  52. {
  53. *result = *first;
  54. ++first;
  55. ++result;
  56. }
  57. return result;
  58. }
  59. }
  60. }
  61. template <class I>
  62. inline BOOST_CXX14_CONSTEXPR bool equal(const I* first, const I* last, const I* other)
  63. {
  64. while (first != last)
  65. {
  66. if (*first != *other)
  67. return false;
  68. ++first;
  69. ++other;
  70. }
  71. return true;
  72. }
  73. }
  74. }
  75. } // namespace boost::multiprecision::std_constexpr
  76. #endif