xref: /freebsd/contrib/llvm-project/libcxx/include/__algorithm/shift_left.h (revision 2ccfa855b2fc331819953e3de1b1c15ce5b95a7e)
1  //===----------------------------------------------------------------------===//
2  //
3  // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4  // See https://llvm.org/LICENSE.txt for license information.
5  // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6  //
7  //===----------------------------------------------------------------------===//
8  
9  #ifndef _LIBCPP___ALGORITHM_SHIFT_LEFT_H
10  #define _LIBCPP___ALGORITHM_SHIFT_LEFT_H
11  
12  #include <__algorithm/move.h>
13  #include <__config>
14  #include <__iterator/iterator_traits.h>
15  #include <type_traits>
16  
17  #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18  #  pragma GCC system_header
19  #endif
20  
21  _LIBCPP_BEGIN_NAMESPACE_STD
22  
23  #if _LIBCPP_STD_VER > 17
24  
25  template <class _ForwardIterator>
26  inline _LIBCPP_INLINE_VISIBILITY constexpr
27  _ForwardIterator
28  shift_left(_ForwardIterator __first, _ForwardIterator __last,
29             typename iterator_traits<_ForwardIterator>::difference_type __n)
30  {
31      if (__n == 0) {
32          return __last;
33      }
34  
35      _ForwardIterator __m = __first;
36      if constexpr (__is_cpp17_random_access_iterator<_ForwardIterator>::value) {
37          if (__n >= __last - __first) {
38              return __first;
39          }
40          __m += __n;
41      } else {
42          for (; __n > 0; --__n) {
43              if (__m == __last) {
44                  return __first;
45              }
46              ++__m;
47          }
48      }
49      return _VSTD::move(__m, __last, __first);
50  }
51  
52  #endif // _LIBCPP_STD_VER > 17
53  
54  _LIBCPP_END_NAMESPACE_STD
55  
56  #endif // _LIBCPP___ALGORITHM_SHIFT_LEFT_H
57