AUI Framework  master
Cross-platform base for C++ UI apps
Loading...
Searching...
No Matches
algorithms.h
    1/*
    2 * AUI Framework - Declarative UI toolkit for modern C++20
    3 * Copyright (C) 2020-2025 Alex2772 and Contributors
    4 *
    5 * SPDX-License-Identifier: MPL-2.0
    6 *
    7 * This Source Code Form is subject to the terms of the Mozilla Public
    8 * License, v. 2.0. If a copy of the MPL was not distributed with this
    9 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
   10 */
   11
   12//
   13// Created by Alex2772 on 11/28/2021.
   14//
   15
   16#pragma once
   17
   18#include <cstdint>
   19#include <cstddef>
   20#include <cmath>
   21#include "iterators.h"
   22
   23namespace aui {
   24
   28    enum class BinarySearchResult {
   32        MATCH,
   33
   37         LEFT,
   38
   42        RIGHT
   43    };
   44
   45
   50    template<typename Predicate, typename Iterator>
   51    struct BinarySearchNearestToZero {
   52    public:
   53        BinarySearchNearestToZero(Predicate predicate, aui::range<Iterator> range): mPredicate(std::move(predicate)), mRange(range) {}
   54
   55        BinarySearchResult operator()(Iterator c) {
   56            auto next = std::next(c);
   57            if (next == mRange.end()) {
   58                return BinarySearchResult::MATCH;
   59            }
   60
   61            auto v1 = mPredicate(c);
   62            auto v2 = mPredicate(next);
   63
   64            if (v1 <= 0 && v2 > 0) {
   65                if (v2 + v1 < 0) {
   66                    return BinarySearchResult::RIGHT;
   67                }
   68                return BinarySearchResult::MATCH;
   69            }
   70            if (v1 > 0) {
   71                if (mRange.begin() == c) {
   72                    return BinarySearchResult::MATCH;
   73                }
   74                if (auto v0 = mPredicate(std::prev(c)); v1 + v0 < 0) {
   75                    return BinarySearchResult::MATCH;
   76                }
   77                return BinarySearchResult::LEFT;
   78            }
   79
   80            return BinarySearchResult::RIGHT;
   81        }
   82    private:
   83        Predicate mPredicate;
   84        aui::range<Iterator> mRange;
   85    };
   86
   87
  130    template<typename Iterator, typename Predicate>
  131    Iterator binary_search(Iterator begin, Iterator end, Predicate predicate) {
  132        static_assert(std::is_same_v<BinarySearchResult, decltype(predicate(std::declval<Iterator>()))>, "predicate should return BinarySearchResult");
  133
  134        size_t rangeEnd = end - begin;
  135        size_t rangeBegin = 0;
  136
  137
  138        for (size_t i; rangeBegin < rangeEnd; ) {
  139            i = (rangeEnd - rangeBegin - 1) / 2 + rangeBegin;
  140            auto it = begin + i;
  141            switch (predicate(it)) {
  142                case BinarySearchResult::MATCH:
  143                    return it;
  144
  145                case BinarySearchResult::RIGHT:
  146                    rangeBegin = i + 1;
  147                    break;
  148                case BinarySearchResult::LEFT:
  149                    rangeEnd = i;
  150                    break;
  151            }
  152
  153        }
  154        return end;
  155    }
  156}
Definition concepts.h:125
Definition iterators.h:50