;;;;
;;;; srfi-223.stk		-- Implementation of SRFI-223
;;;;
;;;; Copyright © 2021 Jeronimo Pellegrini - <j_p@aleph0.info>
;;;;
;;;;
;;;; This program is free software; you can redistribute it and/or modify
;;;; it under the terms of the GNU General Public License as published by
;;;; the Free Software Foundation; either version 2 of the License, or
;;;; (at your option) any later version.
;;;;
;;;; This program is distributed in the hope that it will be useful,
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;;; GNU General Public License for more details.
;;;;
;;;; You should have received a copy of the GNU General Public License
;;;; along with this program; if not, write to the Free Software
;;;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
;;;; USA.
;;;;
;;;; This file is a derivative work from the Daphne Preston-Kendal
;;;; implementation of this SRFI, it is copyrighted as:
;;;;
;;;;;;;   Copyright (C) 2021 Daphne Preston-Kendal.
;;;;;;;
;;;;;;; Permission is hereby granted, free of charge, to any person obtaining
;;;;;;; a copy of this software and associated documentation
;;;;;;; files (the "Software"), to deal in the Software without restriction,
;;;;;;; including without limitation the rights to use, copy, modify, merge,
;;;;;;; publish, distribute, sublicense, and/or sell copies of the Software,
;;;;;;; and to permit persons to whom the Software is furnished to do so,
;;;;;;; subject to the following conditions:
;;;;;;;
;;;;;;; The above copyright notice and this permission notice (including the
;;;;;;; next paragraph) shall be included in all copies or substantial
;;;;;;; portions of the Software.
;;;;;;;
;;;;;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
;;;;;;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
;;;;;;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
;;;;;;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
;;;;;;; LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
;;;;;;; OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
;;;;;;; WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
;;;;
;;;;
;;;;           Author: Jeronimo Pellegrini [j_p@aleph0.info]
;;;;    Creation date: 27-Jul-2021 16:01 (jpellegrini)
;;;;

(define-module srfi/223
  
  (export bisect-left bisect-right
          bisection
          vector-bisect-left vector-bisect-right)

  
(define (bisect-left a val ref less? lo hi)
  (if (>= lo hi) lo
      (let ((mid (floor-quotient (+ lo hi) 2)))
        (if (less? (ref a mid) val)
            (bisect-left a val ref less? (+ mid 1) hi)
            (bisect-left a val ref less? lo mid)))))

(define (bisect-right a val ref less? lo hi)
  (if (>= lo hi) lo
      (let ((mid (floor-quotient (+ lo hi) 2)))
        (if (less? val (ref a mid))
            (bisect-right a val ref less? lo mid)
            (bisect-right a val ref less? (+ mid 1) hi)))))

(define bisection
  (case-lambda
    ((ref lo-hi-proc)
     (values
      (case-lambda
       ((a val less?)
        (let-values (((lo hi) (lo-hi-proc a)))
          (bisect-left a val ref less? lo hi)))
       ((a val less? lo hi)
        (bisect-left a val ref less? lo hi)))
      (case-lambda
       ((a val less?)
        (let-values (((lo hi) (lo-hi-proc a)))
          (bisect-right a val ref less? lo hi)))
       ((a val less? lo hi)
        (bisect-right a val ref less? lo hi)))))
    ((ref)
     (bisection ref
                (lambda (a) (error "both lo and hi arguments must be given to this procedure"))))))

(define-values (vector-bisect-left vector-bisect-right)
  (bisection vector-ref (lambda (v) (values 0 (vector-length v)))))

) ;;; END of module SRFI-223

(provide "srfi/223")
