Add slice swap benchmark.

Adds a benchmark of various different ways of swapping the elements of
two slices, including several implementations in C.

Change-Id: I7ff490aefee6edfe5d7630b851278ce1fc385e8c
diff --git a/src/bindings.rs b/src/bindings.rs
new file mode 100644
index 0000000..ca24cc3
--- /dev/null
+++ b/src/bindings.rs
@@ -0,0 +1,6 @@
+#![allow(dead_code)]
+#![allow(non_upper_case_globals)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+
+include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
diff --git a/src/cswap.rs b/src/cswap.rs
new file mode 100644
index 0000000..b509481
--- /dev/null
+++ b/src/cswap.rs
@@ -0,0 +1,35 @@
+//extern "C" fn swap_loop(a: *mut cty::c_char, b: *mut cty::c_char, n: cty::c_int);
+
+use crate::bindings;
+use std::cmp::min;
+use std::mem::size_of;
+
+pub fn cswap_loop<T>(a: &mut [T], b: &mut [T]) {
+    unsafe {
+        bindings::swap_loop(
+            a.as_mut_ptr() as *mut i8,
+            b.as_mut_ptr() as *mut i8,
+            (size_of::<T>() * min(a.len(), b.len())) as bindings::size_t,
+        )
+    }
+}
+
+pub fn cswap_malloc<T>(a: &mut [T], b: &mut [T]) {
+    unsafe {
+        bindings::swap_malloc(
+            a.as_mut_ptr() as *mut i8,
+            b.as_mut_ptr() as *mut i8,
+            (size_of::<T>() * min(a.len(), b.len())) as bindings::size_t,
+        )
+    }
+}
+
+pub fn cswap_alloca<T>(a: &mut [T], b: &mut [T]) {
+    unsafe {
+        bindings::swap_alloca(
+            a.as_mut_ptr() as *mut i8,
+            b.as_mut_ptr() as *mut i8,
+            (size_of::<T>() * min(a.len(), b.len())) as bindings::size_t,
+        )
+    }
+}
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..62e269a
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,7 @@
+extern crate cty;
+extern crate num;
+
+mod bindings;
+
+pub mod cswap;
+pub mod swap;
diff --git a/src/swap.rs b/src/swap.rs
new file mode 100644
index 0000000..ef07130
--- /dev/null
+++ b/src/swap.rs
@@ -0,0 +1,23 @@
+use core::{mem, ptr};
+use num::Num;
+use std::cmp::min;
+
+pub fn swap_loop<T>(a: &mut [T], b: &mut [T]) {
+    for (x, y) in a.iter_mut().zip(b.iter_mut()) {
+        mem::swap(x, y);
+    }
+}
+
+pub fn swap_ptrswap<T>(a: &mut [T], b: &mut [T]) {
+    unsafe { ptr::swap_nonoverlapping(a.as_mut_ptr(), b.as_mut_ptr(), min(a.len(), b.len())) }
+}
+
+/// Exactly equivalent to `swap_2`, but trades the use of unsafe operations against having to know
+/// the exact type and size of the vector at compile time.  Only works with `heapless::Vec`.
+pub fn swap_3<T, N>(a: &mut heapless::Vec<T, N>, b: &mut heapless::Vec<T, N>)
+where
+    N: heapless::ArrayLength<T>,
+    T: Num + Copy,
+{
+    mem::swap(a, b);
+}