fork(2) download
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <type_traits>
  4. #include <vector>
  5. #include <set>
  6. #include <map>
  7. #include <array>
  8.  
  9.  
  10. template <class InputContainer, class OutputType>
  11. struct convert_container;
  12.  
  13. // conversion for the first group of standard containers
  14. template <template <class...> class C, class IT, class OT>
  15. struct convert_container<C<IT>, OT>
  16. {
  17. using type = C<OT>;
  18. };
  19.  
  20. // conversion for the second group of standard containers
  21. template <template <class...> class C, class IK, class IT, class OK, class OT>
  22. struct convert_container<C<IK, IT>, std::pair<OK, OT>>
  23. {
  24. using type = C<OK, OT>;
  25. };
  26.  
  27. // conversion for the third group of standard containers
  28. template
  29. <
  30. template <class, std::size_t> class C, std::size_t N, class IT, class OT
  31. >
  32. struct convert_container<C<IT, N>, OT>
  33. {
  34. using type = C<OT, N>;
  35. };
  36.  
  37. template <typename C, typename T>
  38. using convert_container_t = typename convert_container<C, T>::type;
  39.  
  40. template
  41. <
  42. class InputContainer,
  43. class Functor,
  44. class InputType = typename InputContainer::value_type,
  45. class OutputType = typename std::result_of<Functor(InputType)>::type,
  46. class OutputContainer = convert_container_t<InputContainer, OutputType>
  47. >
  48. OutputContainer transform_container(const InputContainer& ic, Functor f)
  49. {
  50. OutputContainer oc;
  51.  
  52. std::transform(std::begin(ic), std::end(ic), std::inserter(oc, oc.end()), f);
  53.  
  54. return oc;
  55. }
  56.  
  57. int main()
  58. {
  59. std::cout << std::boolalpha;
  60.  
  61. std::vector<int> vi{ 1, 2, 3, 4, 5 };
  62. auto vs = transform_container(vi, [] (int i) { return std::to_string(i); });
  63. std::cout << "std::vector<int> -> std::vector<std::string>: "
  64. << (vs == std::vector<std::string>{"1", "2", "3", "4", "5"}) << std::endl;
  65.  
  66. std::set<int> si{ 5, 10, 15 };
  67. auto sd = transform_container(si, [] (int i) { return i / 2.; });
  68. std::cout << "std::set<int> -> std::set<double>: "
  69. << (sd == std::set<double>{5/2., 10/2., 15/2.}) << std::endl;
  70.  
  71. std::map<int, char> mic{ {1, 'a'}, {2, 'b'}, {3, 'c'} };
  72. auto mci = transform_container
  73. (
  74. mic,
  75. [] (const std::pair<const int, char>& p)
  76. { return std::pair<char, int>(p.second, p.first); }
  77. );
  78. std::cout << "std::map<int, char> -> std::map<char, int>: "
  79. << (mci == std::map<char, int>{{'a', 1}, {'b', 2}, {'c', 3}}) << std::endl;
  80.  
  81. // doesn't compile because std::array haven't insert method
  82. // which is needed due to std::inserter
  83. /*std::array<int, 3> ai{ 5, 10, 15 };
  84.   auto ad = transform_container(ai, [] (int i) { return i / 2.; });
  85.   std::cout << "std::array<int, 3> -> std::array<double, 3>: "
  86.   << (ad == std::array<double, 3>{5/2., 10/2., 15/2.}) << std::endl;*/
  87. }
Success #stdin #stdout 0s 3436KB
stdin
Standard input is empty
stdout
std::vector<int> -> std::vector<std::string>: true
std::set<int> -> std::set<double>: true
std::map<int, char> -> std::map<char, int>: true