this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2/*
3 * Main authors:
4 * Christian Schulte <schulte@gecode.org>
5 *
6 * Contributing authors:
7 * Samuel Gagnon <samuel.gagnon92@gmail.com>
8 *
9 * Copyright:
10 * Christian Schulte, 2005
11 * Samuel Gagnon, 2018
12 *
13 * This file is part of Gecode, the generic constraint
14 * development environment:
15 * http://www.gecode.org
16 *
17 * Permission is hereby granted, free of charge, to any person obtaining
18 * a copy of this software and associated documentation files (the
19 * "Software"), to deal in the Software without restriction, including
20 * without limitation the rights to use, copy, modify, merge, publish,
21 * distribute, sublicense, and/or sell copies of the Software, and to
22 * permit persons to whom the Software is furnished to do so, subject to
23 * the following conditions:
24 *
25 * The above copyright notice and this permission notice shall be
26 * included in all copies or substantial portions of the Software.
27 *
28 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
32 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
33 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
34 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 *
36 */
37
38namespace Gecode {
39
40 /**
41 * \brief Base-class for constant views
42 * \ingroup TaskVarView
43 */
44 template<class View>
45 class ConstView {
46 public:
47 /// The variable implementation type corresponding to the constant view
48 typedef typename View::VarImpType VarImpType;
49 /// The variable type corresponding to the constant view
50 typedef typename View::VarType VarType;
51 /// \name Generic view information
52 //@{
53 /// Return degree (number of subscribed propagators and advisors)
54 unsigned int degree(void) const;
55 /// Return accumulated failure count
56 double afc(void) const;
57 /// Return whether this view is derived from a VarImpView
58 static bool varderived(void);
59 /// Return dummy variable implementation of view
60 VarImpType* varimp(void) const;
61#ifdef GECODE_HAS_CBS
62 /// Return dummy id
63 unsigned int id(void) const;
64#endif
65 //@}
66
67 /// \name Domain tests
68 //@{
69 /// Test whether view is assigned
70 bool assigned(void) const;
71 //@}
72
73 /// \name View-dependent propagator support
74 //@{
75 /// Schedule propagator \a p with modification event \a me
76 static void schedule(Space& home, Propagator& p, ModEvent me);
77 /// Return modification event for view type in \a med
78 static ModEvent me(const ModEventDelta& med);
79 /// Translate modification event \a me to modification event delta for view
80 static ModEventDelta med(ModEvent me);
81 //@}
82
83 /// \name Dependencies
84 //@{
85 /**
86 * \brief Subscribe propagator \a p with propagation condition \a pc to view
87 *
88 * In case \a schedule is false, the propagator is just subscribed but
89 * not scheduled for execution (this must be used when creating
90 * subscriptions during propagation).
91 */
92 void subscribe(Space& home, Propagator& p, PropCond pc, bool schedule=true);
93 /// Cancel subscription of propagator \a p with propagation condition \a pc to view
94 void cancel(Space& home, Propagator& p, PropCond pc);
95 /// Re-schedule propagator \a p with propagation condition \a pc
96 void reschedule(Space& home, Propagator& p, PropCond pc);
97 /** \brief Subscribe advisor \a a to view
98 *
99 * If \a fail is true, run the advisor also on failure. This
100 * feature is undocumented.
101 */
102 void subscribe(Space& home, Advisor& a, bool fail=false);
103 /// Cancel subscription of advisor \a a
104 void cancel(Space& home, Advisor& a, bool fail=false);
105 //@}
106
107 /// \name Delta information for advisors
108 //@{
109 /// Return modification event
110 static ModEvent modevent(const Delta& d);
111 //@}
112
113 /// \name Cloning
114 //@{
115 /// Update this view to be a clone of view \a y
116 void update(Space& home, ConstView& y);
117 //@}
118
119 /// \name Ordering
120 //@{
121 /// Whether this view comes before view \a y (arbitray order)
122 bool operator <(const ConstView& y) const;
123 //@}
124 };
125
126
127
128 /**
129 * \brief Base-class for variable implementation views
130 * \ingroup TaskVarView
131 */
132 template<class Var>
133 class VarImpView {
134 public:
135 /// The variable type corresponding to the view
136 typedef Var VarType;
137 /// The variable implementation type corresponding to the view
138 typedef typename Var::VarImpType VarImpType;
139 protected:
140 /// Pointer to variable implementation
141 VarImpType* x;
142 /// Default constructor
143 VarImpView(void);
144 /// Initialize with variable implementation \a y
145 VarImpView(VarImpType* y);
146 /// Set variable implementation to \a y
147 void varimp(VarImpType* y);
148 public:
149 /// \name Generic view information
150 //@{
151 /// Return whether this view is derived from a VarImpView
152 static bool varderived(void);
153 /// Return variable implementation of view
154 VarImpType* varimp(void) const;
155 /// Return degree (number of subscribed propagators and advisors)
156 unsigned int degree(void) const;
157 /// Return accumulated failure count
158 double afc(void) const;
159#ifdef GECODE_HAS_CBS
160 /// Return id of implementation of view
161 unsigned int id(void) const;
162#endif
163 //@}
164
165 /// \name Domain tests
166 //@{
167 /// Test whether view is assigned
168 bool assigned(void) const;
169 //@}
170
171 /// \name View-dependent propagator support
172 //@{
173 /// Schedule propagator \a p with modification event \a me
174 static void schedule(Space& home, Propagator& p, ModEvent me);
175 /// Return modification event for view type in \a med
176 static ModEvent me(const ModEventDelta& med);
177 /// Translate modification event \a me to modification event delta for view
178 static ModEventDelta med(ModEvent me);
179 //@}
180
181 /// \name Dependencies
182 //@{
183 /**
184 * \brief Subscribe propagator \a p with propagation condition \a pc to view
185 *
186 * In case \a schedule is false, the propagator is just subscribed but
187 * not scheduled for execution (this must be used when creating
188 * subscriptions during propagation).
189 */
190 void subscribe(Space& home, Propagator& p, PropCond pc, bool schedule=true);
191 /// Cancel subscription of propagator \a p with propagation condition \a pc to view
192 void cancel(Space& home, Propagator& p, PropCond pc);
193 /// Re-schedule propagator \a p with propagation condition \a pc
194 void reschedule(Space& home, Propagator& p, PropCond pc);
195 /** \brief Subscribe advisor \a a to view
196 *
197 * If \a fail is true, run the advisor also on failure. This
198 * feature is undocumented.
199 */
200 void subscribe(Space& home, Advisor& a, bool fail=false);
201 /// Cancel subscription of advisor \a a
202 void cancel(Space& home, Advisor& a, bool fail=false);
203 //@}
204
205 /// \name Delta information for advisors
206 //@{
207 /// Return modification event
208 static ModEvent modevent(const Delta& d);
209 //@}
210
211 /// \name Cloning
212 //@{
213 /// Update this view to be a clone of view \a y
214 void update(Space& home, VarImpView<Var>& y);
215 //@}
216
217 /// \name Ordering
218 //@{
219 /// Whether this view comes before view \a y (arbitray order)
220 bool operator <(const VarImpView& y) const;
221 //@}
222 };
223
224
225 /**
226 * \brief Base-class for derived views
227 * \ingroup TaskVarView
228 */
229 template<class View>
230 class DerivedView {
231 public:
232 /// The variable implementation type belonging to the \a View
233 typedef typename View::VarImpType VarImpType;
234 /// The variable type belonging to the \a View
235 typedef typename View::VarType VarType;
236 protected:
237 /// View from which this view is derived
238 View x;
239 /// Default constructor
240 DerivedView(void);
241 public:
242 /// Initialize with view \a y
243 DerivedView(const View& y);
244 /// \name Generic view information
245 //@{
246 /// Return whether this view is derived from a VarImpView
247 static bool varderived(void);
248 /// Return variable implementation of view
249 VarImpType* varimp(void) const;
250 /// Return view from which this view is derived
251 View base(void) const;
252 /// Return degree (number of subscribed propagators)
253 unsigned int degree(void) const;
254 /// Return accumulated failure count
255 double afc(void) const;
256#ifdef GECODE_HAS_CBS
257 /// Return id of implementation of view
258 unsigned int id(void) const;
259#endif
260 //@}
261
262 /// \name Domain tests
263 //@{
264 /// Test whether view is assigned
265 bool assigned(void) const;
266 //@}
267
268 /// \name View-dependent propagator support
269 //@{
270 /// Schedule propagator \a p with modification event \a me
271 static void schedule(Space& home, Propagator& p, ModEvent me);
272 /// Return modification event for view type in \a med
273 static ModEvent me(const ModEventDelta& med);
274 /// Translate modification event \a me to modification event delta for view
275 static ModEventDelta med(ModEvent);
276 //@}
277
278 /// \name Dependencies
279 //@{
280 /**
281 * \brief Subscribe propagator \a p with propagation condition \a pc to view
282 *
283 * In case \a schedule is false, the propagator is just subscribed but
284 * not scheduled for execution (this must be used when creating
285 * subscriptions during propagation).
286 */
287 void subscribe(Space& home, Propagator& p, PropCond pc, bool schedule=true);
288 /// Cancel subscription of propagator \a p with propagation condition \a pc to view
289 void cancel(Space& home, Propagator& p, PropCond pc);
290 /// Re-schedule propagator \a p with propagation condition \a pc
291 void reschedule(Space& home, Propagator& p, PropCond pc);
292 /** \brief Subscribe advisor \a a to view
293 *
294 * If \a fail is true, run the advisor also on failure. This
295 * feature is undocumented.
296 */
297 void subscribe(Space& home, Advisor& a, bool fail=false);
298 /// Cancel subscription of advisor \a a
299 void cancel(Space& home, Advisor& a, bool fail=false);
300 //@}
301
302 /// \name Delta information for advisors
303 //@{
304 /// Return modification event
305 static ModEvent modevent(const Delta& d);
306 //@}
307
308 /// \name Cloning
309 //@{
310 /// Update this view to be a clone of view \a y
311 void update(Space& home, DerivedView<View>& y);
312 //@}
313
314 /// \name Ordering
315 //@{
316 /// Whether this view comes before view \a y (arbitray order)
317 bool operator <(const DerivedView<View>& y) const;
318 //@}
319 };
320
321
322 /**
323 * \brief Test whether views share same variable
324 * \ingroup TaskVarView
325 */
326 template<class ViewA, class ViewB>
327 bool shared(const ConstView<ViewA>&, const ConstView<ViewB>&);
328 /**
329 * \brief Test whether views share same variable
330 * \ingroup TaskVarView
331 */
332 template<class Var, class View>
333 bool shared(const VarImpView<Var>&, const ConstView<View>&);
334 /**
335 * \brief Test whether views share same variable
336 * \ingroup TaskVarView
337 */
338 template<class ViewA, class ViewB>
339 bool shared(const DerivedView<ViewA>&, const ConstView<ViewB>&);
340 /**
341 * \brief Test whether views share same variable
342 * \ingroup TaskVarView
343 */
344 template<class View, class Var>
345 bool shared(const ConstView<View>&, const VarImpView<Var>&);
346 /**
347 * \brief Test whether views share same variable
348 * \ingroup TaskVarView
349 */
350 template<class ViewA, class ViewB>
351 bool shared(const ConstView<ViewA>&, const DerivedView<ViewB>&);
352 /**
353 * \brief Test whether views share same variable
354 * \ingroup TaskVarView
355 */
356 template<class VarA, class VarB>
357 bool shared(const VarImpView<VarA>&, const VarImpView<VarB>&);
358 /**
359 * \brief Test whether views share same variable
360 * \ingroup TaskVarView
361 */
362 template<class Var, class View>
363 bool shared(const VarImpView<Var>&, const DerivedView<View>&);
364 /**
365 * \brief Test whether views share same variable
366 * \ingroup TaskVarView
367 */
368 template<class View, class Var>
369 bool shared(const DerivedView<View>&, const VarImpView<Var>&);
370 /**
371 * \brief Test whether views share same variable
372 * \ingroup TaskVarView
373 */
374 template<class ViewA, class ViewB>
375 bool shared(const DerivedView<ViewA>&, const DerivedView<ViewB>&);
376
377
378 /*
379 * Constant view: has no variable implementation
380 *
381 */
382 template<class View>
383 forceinline unsigned int
384 ConstView<View>::degree(void) const {
385 return 0;
386 }
387 template<class View>
388 forceinline double
389 ConstView<View>::afc(void) const {
390 return 0.0;
391 }
392 template<class View>
393 forceinline bool
394 ConstView<View>::varderived(void) {
395 return false;
396 }
397 template<class View>
398 forceinline typename View::VarImpType*
399 ConstView<View>::varimp(void) const {
400 return nullptr;
401 }
402#ifdef GECODE_HAS_CBS
403 template<class View>
404 forceinline unsigned int
405 ConstView<View>::id(void) const {
406 return 0;
407 }
408#endif
409 template<class View>
410 forceinline bool
411 ConstView<View>::assigned(void) const {
412 return true;
413 }
414 template<class View>
415 forceinline void
416 ConstView<View>::subscribe(Space& home, Propagator& p, PropCond,
417 bool schedule) {
418 if (schedule)
419 View::schedule(home,p,ME_GEN_ASSIGNED);
420 }
421 template<class View>
422 forceinline void
423 ConstView<View>::cancel(Space&, Propagator&, PropCond) {
424 }
425 template<class View>
426 forceinline void
427 ConstView<View>::reschedule(Space& home, Propagator& p, PropCond) {
428 View::schedule(home,p,ME_GEN_ASSIGNED);
429 }
430 template<class View>
431 forceinline void
432 ConstView<View>::subscribe(Space&, Advisor&, bool) {
433 }
434 template<class View>
435 forceinline void
436 ConstView<View>::cancel(Space&, Advisor&, bool) {
437 }
438 template<class View>
439 forceinline void
440 ConstView<View>::schedule(Space& home, Propagator& p, ModEvent me) {
441 View::schedule(home,p,me);
442 }
443 template<class View>
444 forceinline ModEvent
445 ConstView<View>::me(const ModEventDelta& med) {
446 return View::me(med);
447 }
448 template<class View>
449 forceinline ModEventDelta
450 ConstView<View>::med(ModEvent me) {
451 return View::med(me);
452 }
453 template<class View>
454 forceinline ModEvent
455 ConstView<View>::modevent(const Delta& d) {
456 (void) d;
457 return ME_GEN_NONE;
458 }
459 template<class View>
460 forceinline void
461 ConstView<View>::update(Space&, ConstView<View>&) {
462 }
463 template<class View>
464 forceinline bool
465 ConstView<View>::operator <(const ConstView<View>&) const {
466 return true;
467 }
468
469
470 /*
471 * Variable view: contains a pointer to a variable implementation
472 *
473 */
474 template<class Var>
475 forceinline
476 VarImpView<Var>::VarImpView(void)
477 : x(nullptr) {}
478 template<class Var>
479 forceinline
480 VarImpView<Var>::VarImpView(VarImpType* y)
481 : x(y) {}
482 template<class Var>
483 forceinline void
484 VarImpView<Var>::varimp(VarImpType* y) {
485 x=y;
486 }
487 template<class Var>
488 forceinline bool
489 VarImpView<Var>::varderived(void) {
490 return true;
491 }
492 template<class Var>
493 forceinline typename Var::VarImpType*
494 VarImpView<Var>::varimp(void) const {
495 return x;
496 }
497 template<class Var>
498 forceinline unsigned int
499 VarImpView<Var>::degree(void) const {
500 return x->degree();
501 }
502 template<class Var>
503 forceinline double
504 VarImpView<Var>::afc(void) const {
505 return x->afc();
506 }
507#ifdef GECODE_HAS_CBS
508 template<class Var>
509 forceinline unsigned int
510 VarImpView<Var>::id(void) const {
511 return x->id();
512 }
513#endif
514 template<class Var>
515 forceinline bool
516 VarImpView<Var>::assigned(void) const {
517 return x->assigned();
518 }
519 template<class Var>
520 forceinline void
521 VarImpView<Var>::subscribe(Space& home, Propagator& p, PropCond pc,
522 bool schedule) {
523 x->subscribe(home,p,pc,schedule);
524 }
525 template<class Var>
526 forceinline void
527 VarImpView<Var>::cancel(Space& home, Propagator& p, PropCond pc) {
528 x->cancel(home,p,pc);
529 }
530 template<class Var>
531 forceinline void
532 VarImpView<Var>::reschedule(Space& home, Propagator& p, PropCond pc) {
533 x->reschedule(home,p,pc);
534 }
535 template<class Var>
536 forceinline void
537 VarImpView<Var>::subscribe(Space& home, Advisor& a, bool fail) {
538 x->subscribe(home,a,fail);
539 }
540 template<class Var>
541 forceinline void
542 VarImpView<Var>::cancel(Space& home, Advisor& a, bool fail) {
543 x->cancel(home,a,fail);
544 }
545 template<class Var>
546 forceinline void
547 VarImpView<Var>::schedule(Space& home, Propagator& p, ModEvent me) {
548 VarImpType::schedule(home,p,me);
549 }
550 template<class Var>
551 forceinline ModEvent
552 VarImpView<Var>::me(const ModEventDelta& med) {
553 return VarImpType::me(med);
554 }
555 template<class Var>
556 forceinline ModEventDelta
557 VarImpView<Var>::med(ModEvent me) {
558 return VarImpType::med(me);
559 }
560 template<class Var>
561 forceinline ModEvent
562 VarImpView<Var>::modevent(const Delta& d) {
563 return VarImpType::modevent(d);
564 }
565 template<class Var>
566 forceinline void
567 VarImpView<Var>::update(Space& home, VarImpView<Var>& y) {
568 x = y.x->copy(home);
569 }
570 template<class Var>
571 forceinline bool
572 VarImpView<Var>::operator <(const VarImpView<Var>& y) const {
573 return this->varimp() < y.varimp();
574 }
575
576
577 /*
578 * Derived view: contain the base view from which they are derived
579 *
580 */
581
582 template<class View>
583 forceinline
584 DerivedView<View>::DerivedView(void) {}
585
586 template<class View>
587 forceinline
588 DerivedView<View>::DerivedView(const View& y)
589 : x(y) {}
590
591 template<class View>
592 forceinline bool
593 DerivedView<View>::varderived(void) {
594 return View::varderived();
595 }
596
597 template<class View>
598 forceinline typename View::VarImpType*
599 DerivedView<View>::varimp(void) const {
600 return x.varimp();
601 }
602
603 template<class View>
604 forceinline View
605 DerivedView<View>::base(void) const {
606 return x;
607 }
608
609 template<class View>
610 forceinline unsigned int
611 DerivedView<View>::degree(void) const {
612 return x.degree();
613 }
614 template<class View>
615 forceinline double
616 DerivedView<View>::afc(void) const {
617 return x.afc();
618 }
619#ifdef GECODE_HAS_CBS
620 template<class View>
621 forceinline unsigned int
622 DerivedView<View>::id(void) const {
623 return x.id();
624 }
625#endif
626 template<class View>
627 forceinline bool
628 DerivedView<View>::assigned(void) const {
629 return x.assigned();
630 }
631
632 template<class View>
633 forceinline void
634 DerivedView<View>::schedule(Space& home, Propagator& p, ModEvent me) {
635 return View::schedule(home,p,me);
636 }
637 template<class View>
638 forceinline ModEvent
639 DerivedView<View>::me(const ModEventDelta& med) {
640 return View::me(med);
641 }
642 template<class View>
643 forceinline ModEventDelta
644 DerivedView<View>::med(ModEvent me) {
645 return View::med(me);
646 }
647
648 template<class View>
649 forceinline void
650 DerivedView<View>::subscribe(Space& home, Propagator& p, PropCond pc,
651 bool schedule) {
652 x.subscribe(home,p,pc,schedule);
653 }
654 template<class View>
655 forceinline void
656 DerivedView<View>::cancel(Space& home, Propagator& p, PropCond pc) {
657 x.cancel(home,p,pc);
658 }
659 template<class View>
660 forceinline void
661 DerivedView<View>::reschedule(Space& home, Propagator& p, PropCond pc) {
662 x.reschedule(home,p,pc);
663 }
664 template<class View>
665 forceinline void
666 DerivedView<View>::subscribe(Space& home, Advisor& a, bool fail) {
667 x.subscribe(home,a,fail);
668 }
669 template<class View>
670 forceinline void
671 DerivedView<View>::cancel(Space& home, Advisor& a, bool fail) {
672 x.cancel(home,a,fail);
673 }
674 template<class View>
675 forceinline ModEvent
676 DerivedView<View>::modevent(const Delta& d) {
677 return View::modevent(d);
678 }
679 template<class View>
680 forceinline void
681 DerivedView<View>::update(Space& home, DerivedView<View>& y) {
682 x.update(home,y.x);
683 }
684 template<class View>
685 forceinline bool
686 DerivedView<View>::operator <(const DerivedView<View>& y) const {
687 return base() < y.base();
688 }
689
690
691 /*
692 * Tests whether two views are the same
693 *
694 */
695
696 /// Test whether two views are the same
697 template<class ViewA, class ViewB>
698 forceinline bool
699 operator ==(const ConstView<ViewA>&, const ConstView<ViewB>&) {
700 return false;
701 }
702 /// Test whether two views are the same
703 template<class Var, class View>
704 forceinline bool
705 operator ==(const ConstView<View>&, const VarImpView<Var>&) {
706 return false;
707 }
708 /// Test whether two views are the same
709 template<class ViewA, class ViewB>
710 forceinline bool
711 operator ==(const ConstView<ViewA>&, const DerivedView<ViewB>&) {
712 return false;
713 }
714 /// Test whether two views are the same
715 template<class Var, class View>
716 forceinline bool
717 operator ==(const VarImpView<Var>&, const ConstView<View>&) {
718 return false;
719 }
720 /// Test whether two views are the same
721 template<class Var, class View>
722 forceinline bool
723 operator ==(const VarImpView<Var>&, const DerivedView<View>&) {
724 return false;
725 }
726 /// Test whether two views are the same
727 template<class ViewX, class ViewY>
728 forceinline bool
729 operator ==(const DerivedView<ViewX>&, const ConstView<ViewY>&) {
730 return false;
731 }
732 /// Test whether two views are the same
733 template<class View, class Var>
734 forceinline bool
735 operator ==(const DerivedView<View>&, const VarImpView<Var>&) {
736 return false;
737 }
738 /// Test whether two views are not the same
739 template<class ViewX, class ViewY>
740 forceinline bool
741 operator ==(const DerivedView<ViewX>&, const DerivedView<ViewY>&) {
742 return false;
743 }
744 /// Test whether two views are the same
745 template<class VarX, class VarY>
746 forceinline bool
747 operator ==(const VarImpView<VarX>& x, const VarImpView<VarY>& y) {
748 return x.varimp() == y.varimp();
749 }
750
751 /// Test whether two views are not the same
752 template<class ViewA, class ViewB>
753 forceinline bool
754 operator !=(const ConstView<ViewA>&, const ConstView<ViewB>&) {
755 return true;
756 }
757 /// Test whether two views are not the same
758 template<class Var, class View>
759 forceinline bool
760 operator !=(const ConstView<View>&, const VarImpView<Var>&) {
761 return true;
762 }
763 /// Test whether two views are not the same
764 template<class ViewA, class ViewB>
765 forceinline bool
766 operator !=(const ConstView<ViewA>&, const DerivedView<ViewB>&) {
767 return true;
768 }
769 /// Test whether two views are not the same
770 template<class Var, class View>
771 forceinline bool
772 operator !=(const VarImpView<Var>&, const ConstView<View>&) {
773 return true;
774 }
775 /// Test whether two views are not the same
776 template<class Var, class View>
777 forceinline bool
778 operator !=(const VarImpView<Var>&, const DerivedView<View>&) {
779 return true;
780 }
781 /// Test whether two views are the same
782 template<class ViewX, class ViewY>
783 forceinline bool
784 operator !=(const DerivedView<ViewX>&, const ConstView<ViewY>&) {
785 return true;
786 }
787 /// Test whether two views are not the same
788 template<class View, class Var>
789 forceinline bool
790 operator !=(const DerivedView<View>&, const VarImpView<Var>&) {
791 return true;
792 }
793 /// Test whether two views are not the same
794 template<class ViewX, class ViewY>
795 forceinline bool
796 operator !=(const DerivedView<ViewX>&, const DerivedView<ViewY>&) {
797 return true;
798 }
799 /// Test whether two views are not the same
800 template<class VarX, class VarY>
801 forceinline bool
802 operator !=(const VarImpView<VarX>& x, const VarImpView<VarY>& y) {
803 return x.varimp() != y.varimp();
804 }
805
806
807 /*
808 * Testing whether two views share the same variable
809 *
810 */
811
812 template<class ViewA, class ViewB>
813 forceinline bool
814 shared(const ConstView<ViewA>&, const ConstView<ViewB>&) {
815 return false;
816 }
817 template<class Var, class View>
818 forceinline bool
819 shared(const VarImpView<Var>&, const ConstView<View>&) {
820 return false;
821 }
822 template<class ViewA, class ViewB>
823 forceinline bool
824 shared(const DerivedView<ViewA>&, const ConstView<ViewB>&) {
825 return false;
826 }
827 template<class View, class Var>
828 forceinline bool
829 shared(const ConstView<View>&, const VarImpView<Var>&) {
830 return false;
831 }
832 template<class ViewA, class ViewB>
833 forceinline bool
834 shared(const ConstView<ViewA>&, const DerivedView<ViewB>&) {
835 return false;
836 }
837 template<class VarA, class VarB>
838 forceinline bool
839 shared(const VarImpView<VarA>& x, const VarImpView<VarB>& y) {
840 return (static_cast<VarImpBase*>(x.varimp()) ==
841 static_cast<VarImpBase*>(y.varimp()));
842 }
843 template<class Var, class View>
844 forceinline bool
845 shared(const VarImpView<Var>& x, const DerivedView<View>& y) {
846 return (View::varderived() &&
847 static_cast<VarImpBase*>(x.varimp()) ==
848 static_cast<VarImpBase*>(y.varimp()));
849 }
850 template<class View, class Var>
851 forceinline bool
852 shared(const DerivedView<View>& x, const VarImpView<Var>& y) {
853 return (View::varderived() &&
854 static_cast<VarImpBase*>(x.varimp()) ==
855 static_cast<VarImpBase*>(y.varimp()));
856 }
857 template<class ViewA, class ViewB>
858 forceinline bool
859 shared(const DerivedView<ViewA>& x, const DerivedView<ViewB>& y) {
860 return (ViewA::varderived() && ViewB::varderived() &&
861 static_cast<VarImpBase*>(x.varimp()) ==
862 static_cast<VarImpBase*>(y.varimp()));
863 }
864
865}
866
867// STATISTICS: kernel-var