xref: /freebsd/contrib/llvm-project/libcxx/include/__algorithm/shift_left.h (revision b3edf4467982447620505a28fc82e38a414c07dc)
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_PUSH_MACROS
21 #include <__undef_macros>
22 
23 _LIBCPP_BEGIN_NAMESPACE_STD
24 
25 #if _LIBCPP_STD_VER >= 20
26 
27 template <class _ForwardIterator>
28 inline _LIBCPP_HIDE_FROM_ABI constexpr _ForwardIterator
29 shift_left(_ForwardIterator __first,
30            _ForwardIterator __last,
31            typename iterator_traits<_ForwardIterator>::difference_type __n) {
32   if (__n == 0) {
33     return __last;
34   }
35 
36   _ForwardIterator __m = __first;
37   if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) {
38     if (__n >= __last - __first) {
39       return __first;
40     }
41     __m += __n;
42   } else {
43     for (; __n > 0; --__n) {
44       if (__m == __last) {
45         return __first;
46       }
47       ++__m;
48     }
49   }
50   return std::move(__m, __last, __first);
51 }
52 
53 #endif // _LIBCPP_STD_VER >= 20
54 
55 _LIBCPP_END_NAMESPACE_STD
56 
57 _LIBCPP_POP_MACROS
58 
59 #endif // _LIBCPP___ALGORITHM_SHIFT_LEFT_H
60