pumpkin_core/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, Clone)]
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 new(propagator_id: PropagatorId) -> PropagatorHandle<P> {
28 Self {
29 id: propagator_id,
30 propagator: PhantomData,
31 }
32 }
33
34 pub(crate) fn propagator_id(self) -> PropagatorId {
36 self.id
37 }
38}
39
40impl<P> Clone for PropagatorHandle<P> {
41 fn clone(&self) -> Self {
42 *self
43 }
44}
45
46impl<P> Copy for PropagatorHandle<P> {}
47
48impl PropagatorStore {
49 pub(crate) fn num_propagators(&self) -> usize {
50 self.propagators.len()
51 }
52
53 pub(crate) fn iter_propagators(&self) -> impl Iterator<Item = &dyn Propagator> + '_ {
54 self.propagators.iter().map(|b| b.as_ref())
55 }
56
57 pub(crate) fn iter_propagators_mut(
58 &mut self,
59 ) -> impl Iterator<Item = &mut Box<dyn Propagator>> + '_ {
60 self.propagators.iter_mut()
61 }
62
63 pub(crate) fn new_propagator<P>(&mut self) -> NewPropagatorSlot<'_, P> {
64 NewPropagatorSlot {
65 underlying_slot: self.propagators.new_slot(),
66 propagator_type: PhantomData,
67 }
68 }
69
70 pub(crate) fn get_propagator<P: Propagator>(&self, handle: PropagatorHandle<P>) -> Option<&P> {
74 self[handle.id].downcast_ref()
75 }
76
77 pub(crate) fn get_propagator_mut<P: Propagator>(
81 &mut self,
82 handle: PropagatorHandle<P>,
83 ) -> Option<&mut P> {
84 self[handle.id].downcast_mut()
85 }
86
87 pub(crate) fn as_propagator_handle<P: Propagator>(
89 &self,
90 propagator_id: PropagatorId,
91 ) -> Option<PropagatorHandle<P>> {
92 if self[propagator_id].is::<P>() {
93 Some(PropagatorHandle {
94 id: propagator_id,
95 propagator: PhantomData,
96 })
97 } else {
98 None
99 }
100 }
101}
102
103impl Index<PropagatorId> for PropagatorStore {
104 type Output = dyn Propagator;
105
106 fn index(&self, index: PropagatorId) -> &Self::Output {
107 self.propagators[index].as_ref()
108 }
109}
110
111impl IndexMut<PropagatorId> for PropagatorStore {
112 fn index_mut(&mut self, index: PropagatorId) -> &mut Self::Output {
113 self.propagators[index].as_mut()
114 }
115}
116
117pub(crate) struct NewPropagatorSlot<'a, P> {
120 underlying_slot: Slot<'a, PropagatorId, Box<dyn Propagator>>,
121 propagator_type: PhantomData<P>,
122}
123
124impl<P: Propagator + 'static> NewPropagatorSlot<'_, P> {
125 pub(crate) fn key(&self) -> PropagatorHandle<P> {
127 PropagatorHandle {
128 id: self.underlying_slot.key(),
129 propagator: PhantomData,
130 }
131 }
132
133 pub(crate) fn populate(self, propagator: P) -> PropagatorHandle<P> {
135 PropagatorHandle {
136 id: self.underlying_slot.populate(Box::new(propagator)),
137 propagator: PhantomData,
138 }
139 }
140}
141
142impl Debug for PropagatorStore {
143 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
144 let propagators: Vec<_> = self
145 .propagators
146 .iter()
147 .map(|_| DebugDyn::from("Propagator"))
148 .collect();
149
150 write!(f, "{propagators:?}")
151 }
152}