iter_swap_example.cpp 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. *
  3. * (C) Copyright John Maddock 1999-2005.
  4. * Use, modification and distribution are subject to the
  5. * Boost Software License, Version 1.0. (See accompanying file
  6. * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. *
  8. * This file provides some example of type_traits usage -
  9. * by "optimising" various algorithms:
  10. *
  11. * opt::iter_swap - uses type_traits to determine whether the iterator is a proxy
  12. * in which case it uses a "safe" approach, otherwise calls swap
  13. * on the assumption that swap may be specialised for the pointed-to type.
  14. *
  15. */
  16. #include <iostream>
  17. #include <typeinfo>
  18. #include <algorithm>
  19. #include <iterator>
  20. #include <vector>
  21. #include <memory>
  22. #include <boost/test/included/prg_exec_monitor.hpp>
  23. #include <boost/type_traits.hpp>
  24. using std::cout;
  25. using std::endl;
  26. using std::cin;
  27. namespace opt{
  28. //
  29. // iter_swap:
  30. // tests whether iterator is a proxy iterator or not, and
  31. // uses optimal form accordingly:
  32. //
  33. namespace detail{
  34. template <typename I>
  35. static void do_swap(I one, I two, const boost::false_type&)
  36. {
  37. typedef typename std::iterator_traits<I>::value_type v_t;
  38. v_t v = *one;
  39. *one = *two;
  40. *two = v;
  41. }
  42. template <typename I>
  43. static void do_swap(I one, I two, const boost::true_type&)
  44. {
  45. using std::swap;
  46. swap(*one, *two);
  47. }
  48. }
  49. template <typename I1, typename I2>
  50. inline void iter_swap(I1 one, I2 two)
  51. {
  52. //
  53. // See is both arguments are non-proxying iterators,
  54. // and if both iterator the same type:
  55. //
  56. typedef typename std::iterator_traits<I1>::reference r1_t;
  57. typedef typename std::iterator_traits<I2>::reference r2_t;
  58. typedef boost::integral_constant<bool,
  59. ::boost::is_reference<r1_t>::value
  60. && ::boost::is_reference<r2_t>::value
  61. && ::boost::is_same<r1_t, r2_t>::value> truth_type;
  62. detail::do_swap(one, two, truth_type());
  63. }
  64. }; // namespace opt
  65. int cpp_main(int argc, char* argv[])
  66. {
  67. //
  68. // testing iter_swap
  69. // really just a check that it does in fact compile...
  70. std::vector<int> v1;
  71. v1.push_back(0);
  72. v1.push_back(1);
  73. std::vector<bool> v2;
  74. v2.push_back(0);
  75. v2.push_back(1);
  76. opt::iter_swap(v1.begin(), v1.begin()+1);
  77. opt::iter_swap(v2.begin(), v2.begin()+1);
  78. return 0;
  79. }