solverforge-solver 0.18.0

Solver engine for SolverForge
Documentation
use std::fmt;

use crate::heuristic::selector::nearby_list_change::CrossEntityDistanceMeter;

use super::super::ListVariableSlot;
use super::{ListAccess, ListAccessCapability, ListAccessError};

pub(super) fn typed_error<S, V, DM, IDM>(
    slot: &ListVariableSlot<S, V, DM, IDM>,
    capability: ListAccessCapability,
) -> ListAccessError {
    ListAccessError {
        capability,
        entity_type_name: slot.entity_type_name,
        variable_name: slot.variable_name,
    }
}

impl<S, V, DM, IDM> ListAccess<S> for ListVariableSlot<S, V, DM, IDM>
where
    V: Clone + PartialEq + Send + Sync + fmt::Debug + 'static,
    DM: Clone + Send + Sync + fmt::Debug + CrossEntityDistanceMeter<S>,
    IDM: Clone + Send + Sync + fmt::Debug + CrossEntityDistanceMeter<S>,
{
    type Element = V;

    fn entity_type_name(&self) -> &'static str {
        self.entity_type_name
    }

    fn variable_name(&self) -> &'static str {
        self.variable_name
    }

    fn descriptor_index(&self) -> usize {
        self.descriptor_index
    }

    fn entity_count(&self, solution: &S) -> usize {
        (self.entity_count)(solution)
    }

    fn element_count(&self, solution: &S) -> usize {
        (self.element_count)(solution)
    }

    fn index_to_element(&self, solution: &S, element_index: usize) -> Option<Self::Element> {
        Some((self.index_to_element)(solution, element_index))
    }

    fn element_source_key(&self, solution: &S, element: &Self::Element) -> usize {
        (self.element_source_key)(solution, element)
    }

    fn assigned_elements(&self, solution: &S) -> Vec<Self::Element> {
        (self.assigned_elements)(solution)
    }

    fn list_len(&self, solution: &S, entity: usize) -> usize {
        (self.list_len)(solution, entity)
    }

    fn list_get(&self, solution: &S, entity: usize, pos: usize) -> Option<Self::Element> {
        (self.list_get)(solution, entity, pos)
    }

    fn list_insert(&self, solution: &mut S, entity: usize, pos: usize, value: Self::Element) {
        (self.list_insert)(solution, entity, pos, value);
    }

    fn list_remove(&self, solution: &mut S, entity: usize, pos: usize) -> Option<Self::Element> {
        (self.list_remove)(solution, entity, pos)
    }

    fn list_set(
        &self,
        solution: &mut S,
        entity: usize,
        pos: usize,
        value: Self::Element,
    ) -> Result<(), ListAccessError> {
        (self.list_set)(solution, entity, pos, value);
        Ok(())
    }

    fn list_reverse(
        &self,
        solution: &mut S,
        entity: usize,
        start: usize,
        end: usize,
    ) -> Result<(), ListAccessError> {
        (self.list_reverse)(solution, entity, start, end);
        Ok(())
    }

    fn sublist_remove(
        &self,
        solution: &mut S,
        entity: usize,
        start: usize,
        end: usize,
    ) -> Result<Vec<Self::Element>, ListAccessError> {
        Ok((self.sublist_remove)(solution, entity, start, end))
    }

    fn sublist_insert(
        &self,
        solution: &mut S,
        entity: usize,
        pos: usize,
        values: Vec<Self::Element>,
    ) -> Result<(), ListAccessError> {
        (self.sublist_insert)(solution, entity, pos, values);
        Ok(())
    }

    fn element_owner(
        &self,
        solution: &S,
        element: &Self::Element,
    ) -> Result<Option<usize>, ListAccessError> {
        self.element_owner_fn
            .map(|owner| owner(solution, element))
            .ok_or_else(|| typed_error(self, ListAccessCapability::ElementOwner))
    }

    fn construction_order_key(
        &self,
        solution: &S,
        element: Self::Element,
    ) -> Result<i64, ListAccessError> {
        self.construction_element_order_key
            .map(|key| key(solution, element))
            .ok_or_else(|| typed_error(self, ListAccessCapability::ConstructionOrderKey))
    }

    fn extend_precedence_successors(
        &self,
        solution: &S,
        element: Self::Element,
        successors: &mut Vec<Self::Element>,
    ) -> Result<(), ListAccessError> {
        let Some(successors_fn) = self.precedence_successors_fn else {
            return Err(typed_error(self, ListAccessCapability::Precedence));
        };
        successors_fn(solution, element, successors);
        Ok(())
    }

    fn precedence_duration(
        &self,
        solution: &S,
        element: Self::Element,
    ) -> Result<usize, ListAccessError> {
        self.precedence_duration_fn
            .map(|duration| duration(solution, element))
            .ok_or_else(|| typed_error(self, ListAccessCapability::Precedence))
    }

    fn cross_position_distance(
        &self,
        solution: &S,
        from_entity: usize,
        from_position: usize,
        to_entity: usize,
        to_position: usize,
    ) -> Result<f64, ListAccessError> {
        Ok(self.cross_distance_meter.distance(
            solution,
            from_entity,
            from_position,
            to_entity,
            to_position,
        ))
    }

    fn intra_position_distance(
        &self,
        solution: &S,
        entity: usize,
        from_position: usize,
        to_position: usize,
    ) -> Result<f64, ListAccessError> {
        Ok(self
            .intra_distance_meter
            .distance(solution, entity, from_position, entity, to_position))
    }
}