Merge pull request #228 from apache/fix_forwarding_iterators

no move if const_iterator
diff --git a/common/include/conditional_forward.hpp b/common/include/conditional_forward.hpp
index 4648b85..71ade84 100644
--- a/common/include/conditional_forward.hpp
+++ b/common/include/conditional_forward.hpp
@@ -38,29 +38,41 @@
 // Forward container as iterators
 
 template<typename Container>
-auto forward_begin(Container&& c) ->
-typename std::enable_if<std::is_lvalue_reference<Container>::value, decltype(c.begin())>::type
+auto forward_begin(Container&& c) -> typename std::enable_if<
+  std::is_lvalue_reference<Container>::value ||
+  std::is_same<typename std::remove_reference<Container>::type::const_iterator, decltype(c.begin())>::value,
+  decltype(c.begin())
+>::type
 {
   return c.begin();
 }
 
 template<typename Container>
-auto forward_begin(Container&& c) ->
-typename std::enable_if<!std::is_lvalue_reference<Container>::value, decltype(std::make_move_iterator(c.begin()))>::type
+auto forward_begin(Container&& c) -> typename std::enable_if<
+  !std::is_lvalue_reference<Container>::value &&
+  !std::is_same<typename std::remove_reference<Container>::type::const_iterator, decltype(c.begin())>::value,
+  decltype(std::make_move_iterator(c.begin()))
+>::type
 {
   return std::make_move_iterator(c.begin());
 }
 
 template<typename Container>
-auto forward_end(Container&& c) ->
-typename std::enable_if<std::is_lvalue_reference<Container>::value, decltype(c.end())>::type
+auto forward_end(Container&& c) -> typename std::enable_if<
+  std::is_lvalue_reference<Container>::value ||
+  std::is_same<typename std::remove_reference<Container>::type::const_iterator, decltype(c.begin())>::value,
+  decltype(c.end())
+>::type
 {
   return c.end();
 }
 
 template<typename Container>
-auto forward_end(Container&& c) ->
-typename std::enable_if<!std::is_lvalue_reference<Container>::value, decltype(std::make_move_iterator(c.end()))>::type
+auto forward_end(Container&& c) -> typename std::enable_if<
+  !std::is_lvalue_reference<Container>::value &&
+  !std::is_same<typename std::remove_reference<Container>::type::const_iterator, decltype(c.begin())>::value,
+  decltype(std::make_move_iterator(c.end()))
+>::type
 {
   return std::make_move_iterator(c.end());
 }