pumpkin_core/engine/cp/propagation/
store.rs1use std::fmt::Debug;
2use std::marker::PhantomData;
3use std::ops::Index;
4use std::ops::IndexMut;
5
6use super::Propagator;
7use super::PropagatorId;
8use crate::containers::KeyedVec;
9use crate::containers::Slot;
10use crate::engine::DebugDyn;
11
12#[derive(Default)]
14pub(crate) struct PropagatorStore {
15 propagators: KeyedVec<PropagatorId, Box<dyn Propagator>>,
16}
17
18#[derive(Debug, PartialEq, Eq, Hash)]
21pub struct PropagatorHandle<P> {
22 id: PropagatorId,
23 propagator: PhantomData<P>,
24}
25
26impl<P> PropagatorHandle<P> {
27 pub(crate) fn propagator_id(self) -> PropagatorId {
29 self.id
30 }
31}
32
33impl<P> Clone for PropagatorHandle<P> {
34 fn clone(&self) -> Self {
35 *self
36 }
37}
38
39impl<P> Copy for PropagatorHandle<P> {}
40
41impl PropagatorStore {
42 pub(crate) fn num_propagators(&self) -> usize {
43 self.propagators.len()
44 }
45
46 pub(crate) fn iter_propagators(&self) -> impl Iterator<Item = &dyn Propagator> + '_ {
47 self.propagators.iter().map(|b| b.as_ref())
48 }
49
50 pub(crate) fn iter_propagators_mut(
51 &mut self,
52 ) -> impl Iterator<Item = &mut Box<dyn Propagator>> + '_ {
53 self.propagators.iter_mut()
54 }
55
56 pub(crate) fn new_propagator<P>(&mut self) -> NewPropagatorSlot<'_, P> {
57 NewPropagatorSlot {
58 underlying_slot: self.propagators.new_slot(),
59 propagator_type: PhantomData,
60 }
61 }
62
63 pub(crate) fn get_propagator_mut<P: Propagator>(
67 &mut self,
68 handle: PropagatorHandle<P>,
69 ) -> Option<&mut P> {
70 self[handle.id].downcast_mut()
71 }
72
73 pub(crate) fn as_propagator_handle<P: Propagator>(
75 &self,
76 propagator_id: PropagatorId,
77 ) -> Option<PropagatorHandle<P>> {
78 if self[propagator_id].is::<P>() {
79 Some(PropagatorHandle {
80 id: propagator_id,
81 propagator: PhantomData,
82 })
83 } else {
84 None
85 }
86 }
87
88 #[cfg(test)]
89 pub(crate) fn keys(&self) -> impl Iterator<Item = PropagatorId> + '_ {
90 self.propagators.keys()
91 }
92}
93
94impl Index<PropagatorId> for PropagatorStore {
95 type Output = dyn Propagator;
96
97 fn index(&self, index: PropagatorId) -> &Self::Output {
98 self.propagators[index].as_ref()
99 }
100}
101
102impl IndexMut<PropagatorId> for PropagatorStore {
103 fn index_mut(&mut self, index: PropagatorId) -> &mut Self::Output {
104 self.propagators[index].as_mut()
105 }
106}
107
108pub(crate) struct NewPropagatorSlot<'a, P> {
111 underlying_slot: Slot<'a, PropagatorId, Box<dyn Propagator>>,
112 propagator_type: PhantomData<P>,
113}
114
115impl<P: Propagator + 'static> NewPropagatorSlot<'_, P> {
116 pub(crate) fn key(&self) -> PropagatorHandle<P> {
118 PropagatorHandle {
119 id: self.underlying_slot.key(),
120 propagator: PhantomData,
121 }
122 }
123
124 pub(crate) fn populate(self, propagator: P) -> PropagatorHandle<P> {
126 PropagatorHandle {
127 id: self.underlying_slot.populate(Box::new(propagator)),
128 propagator: PhantomData,
129 }
130 }
131}
132
133impl Debug for PropagatorStore {
134 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
135 let propagators: Vec<_> = self
136 .propagators
137 .iter()
138 .map(|_| DebugDyn::from("Propagator"))
139 .collect();
140
141 write!(f, "{propagators:?}")
142 }
143}