diff --git a/src/ctypes/ctypes.mli b/src/ctypes/ctypes.mli index b4e21ba7..c1c63f78 100644 --- a/src/ctypes/ctypes.mli +++ b/src/ctypes/ctypes.mli @@ -296,6 +296,11 @@ sig [(((x @ a.(0)) @ a.(1)) ...) @ a.(n-1)] where [n] is the length of the array [a]. *) + val fold_right : ('b -> 'a -> 'a) -> 'b t -> 'a -> 'a + (** [CArray.fold_right f a x] computes + [a.(0) @ (a.(1) @ ( ... (a.(n-1) @ x) ...))] + where [n] is the length of the array [a]. *) + val length : 'a t -> int (** Return the number of elements of the given array. *) diff --git a/src/ctypes/ctypes_memory.ml b/src/ctypes/ctypes_memory.ml index d8adc90c..38a255c2 100644 --- a/src/ctypes/ctypes_memory.ml +++ b/src/ctypes/ctypes_memory.ml @@ -240,6 +240,13 @@ struct r := f !r (unsafe_get a i) done; !r + + let fold_right f a x = + let r = ref x in + for i = length a - 1 downto 0 do + r := f (unsafe_get a i) !r + done; + !r end let make ?finalise s = diff --git a/tests/test-arrays/test_array.ml b/tests/test-arrays/test_array.ml index 0c81ae8a..f02c0067 100644 --- a/tests/test-arrays/test_array.ml +++ b/tests/test-arrays/test_array.ml @@ -147,6 +147,19 @@ let test_fold_left _ = assert_equal r [] +(* + Test the CArray.fold_right function + *) +let test_fold_right _ = + let a = CArray.of_list int [1; 2; 3] in + let r = CArray.fold_right (Printf.sprintf "%d%s") a "." in + assert_equal "123." r; + + let a = CArray.of_list int [] in + let r = CArray.fold_right (fun _ -> assert false) a [] in + assert_equal r [] + + (* Test that creating an array initializes all elements appropriately. *) @@ -270,6 +283,9 @@ let suite = "Array tests" >::: "CArray.fold_left" >:: test_fold_left; + "CArray.fold_right" + >:: test_fold_right; + "array initialization" >:: test_array_initialiation;