aboutsummaryrefslogtreecommitdiff
path: root/Source/Utils/Algorithms/UpperBound.H
blob: 8a528971a7df372f60ae8c8885ad41fdc1544e66 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/* Copyright 2022 Luca Fedeli
 *
 * This file is part of WarpX.
 *
 * License: BSD-3-Clause-LBNL
 */

#ifndef WARPX_UTILS_ALGORITHMS_UPPER_BOUND_H_
#define WARPX_UTILS_ALGORITHMS_UPPER_BOUND_H_

#include <AMReX_Extension.H>
#include <AMReX_GpuQualifiers.H>

namespace utils::algorithms
{

    /** \brief Returns a pointer to the first element in the range [first, last) that is greater than val
     *
     * A re-implementation of the upper_bound algorithm suitable for GPU kernels.
     *
     * @param first: pointer to left limit of the range to consider
     * @param last: pointer to right limit of the range to consider
     * @param val: value to compare the elements of [first, last) to
     */
    template<typename T> AMREX_GPU_DEVICE AMREX_FORCE_INLINE
    const T* upper_bound(const T* first, const T* last, const T& val)
    {
        const T* it;
        size_t count, step;
        count = last-first;
        while(count>0){
            it = first;
            step = count/2;
            it += step;
            if (!(val<*it)){
                first = ++it;
                count -= step + 1;
            }
            else{
                count = step;
            }
        }

        return first;
    }

}

#endif //WARPX_UTILS_ALGORITHMS_UPPER_BOUND_H_