xref: /freebsd/contrib/llvm-project/libcxx/include/__algorithm/shift_left.h (revision 1d479bf6b4741fdc24490ad7179bbef0a78af288)
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  
16  #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17  #  pragma GCC system_header
18  #endif
19  
20  _LIBCPP_BEGIN_NAMESPACE_STD
21  
22  #if _LIBCPP_STD_VER >= 20
23  
24  template <class _ForwardIterator>
25  inline _LIBCPP_INLINE_VISIBILITY constexpr
26  _ForwardIterator
27  shift_left(_ForwardIterator __first, _ForwardIterator __last,
28             typename iterator_traits<_ForwardIterator>::difference_type __n)
29  {
30      if (__n == 0) {
31          return __last;
32      }
33  
34      _ForwardIterator __m = __first;
35      if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) {
36          if (__n >= __last - __first) {
37              return __first;
38          }
39          __m += __n;
40      } else {
41          for (; __n > 0; --__n) {
42              if (__m == __last) {
43                  return __first;
44              }
45              ++__m;
46          }
47      }
48      return _VSTD::move(__m, __last, __first);
49  }
50  
51  #endif // _LIBCPP_STD_VER >= 20
52  
53  _LIBCPP_END_NAMESPACE_STD
54  
55  #endif // _LIBCPP___ALGORITHM_SHIFT_LEFT_H
56