use std::rc::Rc;
use crate::float_ord::FloatOrd;
use std::borrow::Borrow;
use std::cmp::{Ordering, PartialOrd};
use std::hash::{ Hash, Hasher };
use std::ops::Mul;
pub mod c {
use super::*;
use std::cell::RefCell;
use std::ffi::{ CStr, CString };
use std::os::raw::c_char;
use std::rc::Rc;
use std::str::Utf8Error;
use std::sync::{Arc, Mutex};
use std::borrow::ToOwned;
pub fn as_str(s: &*const c_char) -> Result<Option<&str>, Utf8Error> {
if s.is_null() {
Ok(None)
} else {
unsafe {CStr::from_ptr(*s)}
.to_str()
.map(Some)
}
}
pub fn as_cstr(s: &*const c_char) -> Option<&CStr> {
if s.is_null() {
None
} else {
Some(unsafe {CStr::from_ptr(*s)})
}
}
pub fn into_cstring(s: *const c_char) -> Result<Option<CString>, std::ffi::NulError> {
if s.is_null() {
Ok(None)
} else {
CString::new(
unsafe {CStr::from_ptr(s)}.to_bytes()
).map(Some)
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::ptr;
#[test]
fn test_null_cstring() {
assert_eq!(into_cstring(ptr::null()), Ok(None))
}
#[test]
fn test_null_str() {
assert_eq!(as_str(&ptr::null()), Ok(None))
}
}
pub trait COpaquePtr {}
#[repr(transparent)]
pub struct Wrapped<T>(*const RefCell<T>);
impl<T> Wrapped<T> {
pub fn new(value: T) -> Wrapped<T> {
Wrapped::wrap(Rc::new(RefCell::new(value)))
}
pub fn wrap(state: Rc<RefCell<T>>) -> Wrapped<T> {
Wrapped(Rc::into_raw(state))
}
pub unsafe fn unwrap(self) -> Rc<RefCell<T>> {
Rc::from_raw(self.0)
}
pub fn clone_ref(&self) -> Rc<RefCell<T>> {
let used_rc = unsafe { Rc::from_raw(self.0) };
let rc = used_rc.clone();
Rc::into_raw(used_rc); rc
}
}
impl<T> Clone for Wrapped<T> {
fn clone(&self) -> Wrapped<T> {
Wrapped::wrap(self.clone_ref())
}
}
impl<T: Clone> CloneOwned for Wrapped<T> {
type Owned = T;
fn clone_owned(&self) -> T {
let rc = self.clone_ref();
let r = RefCell::borrow(&rc);
r.to_owned()
}
}
impl<T> COpaquePtr for Wrapped<T> {}
#[repr(transparent)]
pub struct ArcWrapped<T>(*const Mutex<T>);
impl<T> ArcWrapped<T> {
pub fn new(value: T) -> Self {
Self::wrap(Arc::new(Mutex::new(value)))
}
pub fn wrap(state: Arc<Mutex<T>>) -> Self {
Self(Arc::into_raw(state))
}
pub unsafe fn unwrap(self) -> Arc<Mutex<T>> {
Arc::from_raw(self.0)
}
pub fn clone_ref(&self) -> Arc<Mutex<T>> {
let used_rc = unsafe { Arc::from_raw(self.0) };
let rc = used_rc.clone();
let _ = Arc::into_raw(used_rc); rc
}
}
impl<T> Clone for ArcWrapped<T> {
fn clone(&self) -> Self {
Self::wrap(self.clone_ref())
}
}
impl<T: Clone> CloneOwned for ArcWrapped<T> {
type Owned = T;
fn clone_owned(&self) -> T {
let rc = self.clone_ref();
let r = rc.lock().unwrap();
r.to_owned()
}
}
}
pub trait CloneOwned {
type Owned;
fn clone_owned(&self) -> Self::Owned;
}
pub fn find_max_double<T, I, F>(iterator: I, get: F)
-> f64
where I: Iterator<Item=T>,
F: Fn(&T) -> f64
{
iterator.map(|value| FloatOrd(get(&value)))
.max().unwrap_or(FloatOrd(0f64))
.0
}
pub trait DivCeil<Rhs = Self> {
type Output;
fn div_ceil(self, rhs: Rhs) -> Self::Output;
}
impl DivCeil for i32 {
type Output = Self;
fn div_ceil(self, other: i32) -> Self::Output {
let d = self / other;
let m = self % other;
if m == 0 { d } else { d + 1}
}
}
#[derive(Debug, Clone, Copy)]
pub struct Rational<T> {
pub numerator: T,
pub denominator: u32,
}
impl<U, T: DivCeil<i32, Output=U>> Rational<T> {
pub fn ceil(self) -> U {
self.numerator.div_ceil(self.denominator as i32)
}
}
impl<T: Mul<i32, Output=T>> Mul<i32> for Rational<T> {
type Output = Self;
fn mul(self, m: i32) -> Self {
Self {
numerator: self.numerator * m,
denominator: self.denominator,
}
}
}
impl<U, T: Mul<U, Output=T>> Mul<Rational<U>> for Rational<T> {
type Output = Self;
fn mul(self, m: Rational<U>) -> Self {
Self {
numerator: self.numerator * m.numerator,
denominator: self.denominator * m.denominator,
}
}
}
impl PartialEq for Rational<i32> {
fn eq(&self, other: &Self) -> bool {
(self.denominator as i64).saturating_mul(other.numerator as i64)
== (other.denominator as i64).saturating_mul(self.numerator as i64)
}
}
impl Eq for Rational<i32> {}
impl Ord for Rational<i32> {
fn cmp(&self, other: &Self) -> Ordering {
(other.denominator as i64).saturating_mul(self.numerator as i64)
.cmp(
&(self.denominator as i64).saturating_mul(other.numerator as i64)
)
}
}
impl PartialOrd for Rational<i32> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
pub struct Pointer<T>(pub Rc<T>);
impl<T> Pointer<T> {
pub fn new(value: T) -> Self {
Pointer(Rc::new(value))
}
}
impl<T> Hash for Pointer<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
(&*self.0 as *const T).hash(state);
}
}
impl<T> PartialEq for Pointer<T> {
fn eq(&self, other: &Pointer<T>) -> bool {
Rc::ptr_eq(&self.0, &other.0)
}
}
impl<T> Eq for Pointer<T> {}
impl<T> Clone for Pointer<T> {
fn clone(&self) -> Self {
Pointer(self.0.clone())
}
}
impl<T> Borrow<Rc<T>> for Pointer<T> {
fn borrow(&self) -> &Rc<T> {
&self.0
}
}
pub trait WarningHandler {
fn handle(&mut self, warning: &str);
}
pub fn vec_remove<T, F: FnMut(&T) -> bool>(v: &mut Vec<T>, pred: F) -> Option<T> {
let idx = v.iter().position(pred);
idx.map(|idx| v.remove(idx))
}
pub fn cycle_count<T, I: Clone + Iterator<Item=T>>(iter: I)
-> impl Iterator<Item=(T, usize)>
{
let numbered_copies = vec![iter].into_iter()
.cycle()
.enumerate();
numbered_copies.flat_map(|(idx, cycle)|
cycle.zip(
vec![idx].into_iter().cycle() )
)
}
#[cfg(test)]
mod tests {
use super::*;
use std::collections::HashSet;
#[test]
fn check_set() {
let mut s = HashSet::new();
let first = Rc::new(1u32);
s.insert(Pointer(first.clone()));
assert_eq!(s.insert(Pointer(Rc::new(2u32))), true);
assert_eq!(s.remove(&Pointer(first)), true);
}
#[test]
fn check_count() {
assert_eq!(
cycle_count(5..8).take(7).collect::<Vec<_>>(),
vec![(5, 0), (6, 0), (7, 0), (5, 1), (6, 1), (7, 1), (5, 2)]
);
}
#[test]
fn check_rational_cmp() {
assert_eq!(
Rational { numerator: 1, denominator: 1 },
Rational { numerator: 1, denominator: 1 },
);
assert_eq!(
Rational { numerator: 1, denominator: 1 },
Rational { numerator: 2, denominator: 2 },
);
assert!(
Rational { numerator: 1, denominator: 1 }
< Rational { numerator: 2, denominator: 1 }
);
}
}