fork download
  1. #include <iostream>
  2. #include <type_traits>
  3. #include <string>
  4. #include <limits>
  5.  
  6. template<typename T>
  7. using StringReplaceIsInPlace = std::conditional_t<std::is_lvalue_reference<T>::value && !std::is_const<std::remove_reference_t<T>>::value, std::true_type, std::false_type>;
  8.  
  9. template<typename Str, typename = std::enable_if_t<StringReplaceIsInPlace<Str>::value>>
  10. Str StringReplace(
  11. Str&& str,
  12. const std::remove_reference_t<Str>& from,
  13. const std::remove_reference_t<Str>& to
  14. ) {
  15. std::cout << "in place: " << __PRETTY_FUNCTION__ << std::endl;
  16. return std::forward<Str>(str);
  17. }
  18.  
  19. template<typename Str, typename = std::enable_if_t<!StringReplaceIsInPlace<Str>::value>>
  20. std::decay_t<Str> StringReplace(
  21. Str&& str, // const lvalues and rvalues
  22. const std::remove_reference_t<Str>& from,
  23. const std::remove_reference_t<Str>& to
  24. ) {
  25. std::cout << "in a copy: " << __PRETTY_FUNCTION__ << std::endl;
  26. std::decay_t<Str> mutableStr{std::forward<Str>(str)};
  27. StringReplace(mutableStr, from, to);
  28. return mutableStr;
  29. }
  30.  
  31. int main()
  32. {
  33. {
  34. std::cout << "lvalue" << std::endl;
  35. std::string v;
  36. StringReplace(v, "", "");
  37. }
  38.  
  39. {
  40. std::cout << std::endl << "const lvalue" << std::endl;
  41. const std::string v;
  42. StringReplace(v, "", "");
  43. }
  44.  
  45. {
  46. std::cout << std::endl << "lvalue reference" << std::endl;
  47. std::string v;
  48. std::string& vref = v;
  49. StringReplace(vref, "", "");
  50. }
  51.  
  52. {
  53. std::cout << std::endl << "const lvalue reference" << std::endl;
  54. std::string v;
  55. const std::string& vref = v;
  56. StringReplace(vref, "", "");
  57. }
  58.  
  59. {
  60. std::cout << std::endl << "rvalue" << std::endl;
  61. std::string v;
  62. StringReplace(std::move(v), "", "");
  63. }
  64.  
  65. {
  66. std::cout << std::endl << "const rvalue" << std::endl;
  67. const std::string v;
  68. StringReplace(std::move(v), "", "");
  69. }
  70.  
  71. {
  72. std::cout << std::endl << "rvalue reference" << std::endl;
  73. std::string&& v = std::string();
  74. StringReplace(v, "", "");
  75. }
  76.  
  77. {
  78. std::cout << std::endl << "const rvalue reference" << std::endl;
  79. const std::string&& v = std::string();
  80. StringReplace(v, "", "");
  81. }
  82.  
  83. {
  84. std::cout << std::endl << "string literal" << std::endl;
  85. StringReplace<std::string>("", "", "");
  86. }
  87.  
  88. return 0;
  89. }
Success #stdin #stdout 0s 4500KB
stdin
Standard input is empty
stdout
lvalue
in place: Str StringReplace(Str&&, std::remove_reference_t<T>&, std::remove_reference_t<T>&) [with Str = std::__cxx11::basic_string<char>&; <template-parameter-1-2> = void; std::remove_reference_t<T> = std::__cxx11::basic_string<char>]

const lvalue
in a copy: std::decay_t<Str> StringReplace(Str&&, std::remove_reference_t<T>&, std::remove_reference_t<T>&) [with Str = const std::__cxx11::basic_string<char>&; <template-parameter-1-2> = void; std::decay_t<Str> = std::__cxx11::basic_string<char>; std::remove_reference_t<T> = const std::__cxx11::basic_string<char>]
in place: Str StringReplace(Str&&, std::remove_reference_t<T>&, std::remove_reference_t<T>&) [with Str = std::__cxx11::basic_string<char>&; <template-parameter-1-2> = void; std::remove_reference_t<T> = std::__cxx11::basic_string<char>]

lvalue reference
in place: Str StringReplace(Str&&, std::remove_reference_t<T>&, std::remove_reference_t<T>&) [with Str = std::__cxx11::basic_string<char>&; <template-parameter-1-2> = void; std::remove_reference_t<T> = std::__cxx11::basic_string<char>]

const lvalue reference
in a copy: std::decay_t<Str> StringReplace(Str&&, std::remove_reference_t<T>&, std::remove_reference_t<T>&) [with Str = const std::__cxx11::basic_string<char>&; <template-parameter-1-2> = void; std::decay_t<Str> = std::__cxx11::basic_string<char>; std::remove_reference_t<T> = const std::__cxx11::basic_string<char>]
in place: Str StringReplace(Str&&, std::remove_reference_t<T>&, std::remove_reference_t<T>&) [with Str = std::__cxx11::basic_string<char>&; <template-parameter-1-2> = void; std::remove_reference_t<T> = std::__cxx11::basic_string<char>]

rvalue
in a copy: std::decay_t<Str> StringReplace(Str&&, std::remove_reference_t<T>&, std::remove_reference_t<T>&) [with Str = std::__cxx11::basic_string<char>; <template-parameter-1-2> = void; std::decay_t<Str> = std::__cxx11::basic_string<char>; std::remove_reference_t<T> = std::__cxx11::basic_string<char>]
in place: Str StringReplace(Str&&, std::remove_reference_t<T>&, std::remove_reference_t<T>&) [with Str = std::__cxx11::basic_string<char>&; <template-parameter-1-2> = void; std::remove_reference_t<T> = std::__cxx11::basic_string<char>]

const rvalue
in a copy: std::decay_t<Str> StringReplace(Str&&, std::remove_reference_t<T>&, std::remove_reference_t<T>&) [with Str = const std::__cxx11::basic_string<char>; <template-parameter-1-2> = void; std::decay_t<Str> = std::__cxx11::basic_string<char>; std::remove_reference_t<T> = const std::__cxx11::basic_string<char>]
in place: Str StringReplace(Str&&, std::remove_reference_t<T>&, std::remove_reference_t<T>&) [with Str = std::__cxx11::basic_string<char>&; <template-parameter-1-2> = void; std::remove_reference_t<T> = std::__cxx11::basic_string<char>]

rvalue reference
in place: Str StringReplace(Str&&, std::remove_reference_t<T>&, std::remove_reference_t<T>&) [with Str = std::__cxx11::basic_string<char>&; <template-parameter-1-2> = void; std::remove_reference_t<T> = std::__cxx11::basic_string<char>]

const rvalue reference
in a copy: std::decay_t<Str> StringReplace(Str&&, std::remove_reference_t<T>&, std::remove_reference_t<T>&) [with Str = const std::__cxx11::basic_string<char>&; <template-parameter-1-2> = void; std::decay_t<Str> = std::__cxx11::basic_string<char>; std::remove_reference_t<T> = const std::__cxx11::basic_string<char>]
in place: Str StringReplace(Str&&, std::remove_reference_t<T>&, std::remove_reference_t<T>&) [with Str = std::__cxx11::basic_string<char>&; <template-parameter-1-2> = void; std::remove_reference_t<T> = std::__cxx11::basic_string<char>]

string literal
in a copy: std::decay_t<Str> StringReplace(Str&&, std::remove_reference_t<T>&, std::remove_reference_t<T>&) [with Str = std::__cxx11::basic_string<char>; <template-parameter-1-2> = void; std::decay_t<Str> = std::__cxx11::basic_string<char>; std::remove_reference_t<T> = std::__cxx11::basic_string<char>]
in place: Str StringReplace(Str&&, std::remove_reference_t<T>&, std::remove_reference_t<T>&) [with Str = std::__cxx11::basic_string<char>&; <template-parameter-1-2> = void; std::remove_reference_t<T> = std::__cxx11::basic_string<char>]