36 #ifndef VIGRA_ACCUMULATOR_GRAMMAR_HXX
37 #define VIGRA_ACCUMULATOR_GRAMMAR_HXX
40 #pragma warning (disable: 4503)
44 #include "metaprogramming.hxx"
86 template <
unsigned NDim>
class MultiHistogram;
90 class PrincipalProjection;
98 template <
int INDEX>
class CoordArg;
147 template <
class A>
class CoordWeighted;
148 template <
class A>
class DataFromHandle;
155 template <
class A>
class Whitened;
246 namespace acc_detail {
257 struct Error___Tag_modifiers_of_same_kind_must_not_be_combined;
260 template <class A, class S=typename acc_detail::ModifierRule<A>::type>
261 struct StandardizeTag
263 typedef typename StandardizeTag<S>::type type;
268 struct StandardizeTag<A, A>
274 template <
class A,
class B>
275 struct StandardizeTag<A, Error___Tag_modifiers_of_same_kind_must_not_be_combined<B> >
276 :
public Error___Tag_modifiers_of_same_kind_must_not_be_combined<B>
279 namespace acc_detail {
283 enum { MinPriority = 1,
284 AccumulatorPriority = 32,
285 PrepareDataPriority = 16,
286 NormalizePriority = 8,
287 AccessDataPriority = 4,
288 WeightingPriority = 2,
291 SubstitutionMask = PrepareDataPriority | AccessDataPriority | WeightingPriority | GlobalPriority };
294 struct ModifierPriority
296 static const int value = AccumulatorPriority;
299 #define VIGRA_MODIFIER_PRIORITY(MODIFIER, VALUE) \
301 struct ModifierPriority<MODIFIER<A> > \
303 static const int value = VALUE; \
306 VIGRA_MODIFIER_PRIORITY(Global, GlobalPriority)
308 VIGRA_MODIFIER_PRIORITY(Weighted, WeightingPriority)
310 VIGRA_MODIFIER_PRIORITY(Coord, AccessDataPriority)
311 VIGRA_MODIFIER_PRIORITY(DataFromHandle, AccessDataPriority)
313 VIGRA_MODIFIER_PRIORITY(DivideByCount, NormalizePriority)
314 VIGRA_MODIFIER_PRIORITY(RootDivideByCount, NormalizePriority)
315 VIGRA_MODIFIER_PRIORITY(DivideUnbiased, NormalizePriority)
316 VIGRA_MODIFIER_PRIORITY(RootDivideUnbiased, NormalizePriority)
318 VIGRA_MODIFIER_PRIORITY(Central, PrepareDataPriority)
319 VIGRA_MODIFIER_PRIORITY(Principal, PrepareDataPriority)
320 VIGRA_MODIFIER_PRIORITY(Whitened, PrepareDataPriority)
323 VIGRA_MODIFIER_PRIORITY(StandardQuantiles, AccumulatorPriority)
325 #undef VIGRA_MODIFIER_PRIORITY
328 template <class A, int TARGET_PRIORITY, int PRIORITY=ModifierPriority<A>::value>
329 struct HasModifierPriority
331 typedef VigraFalseType type;
332 static const bool value =
false;
335 template <
class A,
int TARGET_PRIORITY>
336 struct HasModifierPriority<A, TARGET_PRIORITY, TARGET_PRIORITY>
338 typedef VigraTrueType type;
339 static const bool value =
true;
342 template <
class A,
template <
class>
class B,
int TARGET_PRIORITY,
int PRIORITY>
343 struct HasModifierPriority<B<A>, TARGET_PRIORITY, PRIORITY>
344 :
public HasModifierPriority<A, TARGET_PRIORITY>
347 template <
class A,
template <
class>
class B,
int TARGET_PRIORITY>
348 struct HasModifierPriority<B<A>, TARGET_PRIORITY, TARGET_PRIORITY>
350 typedef VigraTrueType type;
351 static const bool value =
true;
355 template <
class A,
class B>
356 struct ModifierCompare
358 static const int p1 = ModifierPriority<A>::value;
359 static const int p2 = ModifierPriority<B>::value;
360 static const int value = p1 < p2
368 struct ModifierCompareToInner;
370 template <
class A,
template <
class>
class B>
371 struct ModifierCompareToInner<B<A> >
372 :
public ModifierCompare<B<A>, A>
376 template <class A, int compare=ModifierCompareToInner<A>::value>
377 struct ModifierOrder;
381 struct ModifierOrder<A, -1>
387 template <
class A,
template <
class>
class B,
template <
class>
class C>
388 struct ModifierOrder<C<B<A> >, 0>
390 typedef Error___Tag_modifiers_of_same_kind_must_not_be_combined<C<B<A> > > type;
394 template <
class A,
template <
class>
class B,
template <
class>
class C>
395 struct ModifierOrder<C<B<A> >, 1>
397 typedef B<C<A> > type;
400 #define VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(OUTER, INNER, RESULT) \
402 struct ModifierOrder<OUTER<INNER<A > >, 0> \
404 typedef RESULT<A > type; \
408 VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(Central, Central, Central)
409 VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(Principal, Principal, Principal)
410 VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(Whitened, Whitened, Whitened)
413 VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(Principal, Central, Principal)
414 VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(Whitened, Central, Whitened)
415 VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(Whitened, Principal, Whitened)
418 VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(DataFromHandle, Coord, Coord)
420 #undef VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS
423 template <
class A,
template <
class>
class B>
424 struct ModifierRule<B<B<A> > >
429 template <class A, int PRIORITY=ModifierPriority<A>::value>
430 struct RecurseModifier;
432 template <
class A,
template <
class>
class B,
int PRIORITY>
433 struct RecurseModifier<B<A>, PRIORITY>
435 typedef typename ModifierOrder<B<typename StandardizeTag<A>::type> >::type type;
438 template <
class A,
template <
class>
class B>
439 struct RecurseModifier<B<A>, AccumulatorPriority>
447 template <
class A,
template <
class>
class B>
448 struct ModifierRule<B<A> >
449 :
public RecurseModifier<B<A> >
455 #define VIGRA_REDUCE_MODFIER(TEMPLATE, SOURCE, TARGET) \
456 template <TEMPLATE > \
457 struct ModifierRule<SOURCE > \
459 typedef TARGET type; \
465 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Central<CoordinateSystem>, CoordinateSystem)
467 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Whitened<CoordinateSystem>, Principal<CoordinateSystem>)
470 VIGRA_REDUCE_MODFIER(template <class>
class A, A<Count>,
Count)
471 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Weighted<Count>, Weighted<Count>)
472 VIGRA_REDUCE_MODFIER(VIGRA_VOID, CoordWeighted<Count>, Weighted<Count>)
473 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Global<Count>, Global<Count>)
476 VIGRA_REDUCE_MODFIER(
unsigned N, Moment<N>, DivideByCount<PowerSum<N> >)
477 VIGRA_REDUCE_MODFIER(
unsigned N, CentralMoment<N>, DivideByCount<Central<PowerSum<N> > >)
478 VIGRA_REDUCE_MODFIER(class A, CoordWeighted<A>, Weighted<Coord<A> >)
481 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Central<Centralize>, Centralize)
482 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Central<Skewness>, Skewness)
483 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Central<Kurtosis>, Kurtosis)
484 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Central<FlatScatterMatrix>, FlatScatterMatrix)
485 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Central<ScatterMatrixEigensystem>, ScatterMatrixEigensystem)
487 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Principal<Centralize>, PrincipalProjection)
488 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Whitened<Centralize>, Whiten)
489 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Principal<PrincipalProjection>, PrincipalProjection)
490 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Whitened<PrincipalProjection>, Whiten)
491 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Whitened<Whiten>, Whiten)
494 VIGRA_REDUCE_MODFIER(template <class> class A, A<RegionContour>, RegionContour)
496 VIGRA_REDUCE_MODFIER(template <class>
class A, A<ConvexHull>, ConvexHull)
497 VIGRA_REDUCE_MODFIER(template <class>
class A, A<ConvexHullFeatures>, ConvexHullFeatures)
499 VIGRA_REDUCE_MODFIER(template <class>
class A, A<RegionPerimeter>, RegionPerimeter)
500 VIGRA_REDUCE_MODFIER(template <class>
class A, A<RegionCircularity>, RegionCircularity)
501 VIGRA_REDUCE_MODFIER(template <class>
class A, A<RegionEccentricity>, RegionEccentricity)
502 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Weighted<RegionEccentricity>, Weighted<RegionEccentricity>)
505 template <
unsigned N>
506 struct ModifierRule<AbsPowerSum<N> >
508 typedef typename IfBool<(N % 2 == 0), PowerSum<N>, AbsPowerSum<N> >::type type;
512 #undef VIGRA_REDUCE_MODFIER
515 struct ShouldBeWeighted
517 typedef VigraFalseType type;
518 static const bool value =
false;
522 struct ShouldBeWeighted<ArgMinWeight>
524 typedef VigraTrueType type;
525 static const bool value =
true;
529 struct ShouldBeWeighted<ArgMaxWeight>
531 typedef VigraTrueType type;
532 static const bool value =
true;
535 template <
class A,
template <
class>
class B>
536 struct ShouldBeWeighted<B<A> >
537 :
public ShouldBeWeighted<A>
543 struct IsCoordinateFeature
545 typedef VigraFalseType type;
546 static const bool value =
false;
549 template <
class A,
template <
class>
class B>
550 struct IsCoordinateFeature<B<A> >
552 typedef typename IsCoordinateFeature<A>::type type;
553 static const bool value = IsCoordinateFeature<A>::value;
557 struct IsCoordinateFeature<Coord<A> >
559 typedef VigraTrueType type;
560 static const bool value =
true;
564 struct IsPrincipalFeature
566 typedef VigraFalseType type;
567 static const bool value =
false;
570 template <
class A,
template <
class>
class B>
571 struct IsPrincipalFeature<B<A> >
573 typedef typename IsPrincipalFeature<A>::type type;
574 static const bool value = IsPrincipalFeature<A>::value;
578 struct IsPrincipalFeature<Principal<A> >
580 typedef VigraTrueType type;
581 static const bool value =
true;
585 struct IsPrincipalFeature<Whitened<A> >
587 typedef VigraTrueType type;
588 static const bool value =
true;
597 namespace acc_detail {
600 struct DefaultModifier;
603 struct ModifierPriority<DefaultModifier<A> >
605 static const int value = ModifierPriority<A>::value << 1;
608 template <class A, int TargetPriority, int Priority=ModifierPriority<A>::value>
609 struct InsertDefaultModifier
611 typedef DefaultModifier<
typename InsertDefaultModifier<A, (TargetPriority << 1)>::type> type;
614 template <
class A,
int TargetPriority>
615 struct InsertDefaultModifier<A, TargetPriority, TargetPriority>
620 template <class A, int TargetPriority, int Priority=ModifierPriority<A>::value>
623 template <
class A,
int TargetPriority>
624 struct TagLongForm<A, TargetPriority, MaxPriority>
626 typedef typename InsertDefaultModifier<A, TargetPriority>::type type;
629 template <
class A,
template <
class>
class B,
int TargetPriority>
630 struct TagLongForm<B<A>, TargetPriority, MaxPriority>
632 typedef typename InsertDefaultModifier<B<A>, TargetPriority>::type type;
635 template <
class A,
template <
class>
class B,
int TargetPriority,
int Priority>
636 struct TagLongForm<B<A>, TargetPriority, Priority>
638 typedef typename TagLongForm<A, (Priority << 1)>::type Inner;
639 typedef typename InsertDefaultModifier<B<Inner>, TargetPriority>::type type;
642 template <
class A,
template <
class>
class B,
int TargetPriority>
643 struct TagLongForm<B<A>, TargetPriority, TargetPriority>
645 typedef typename TagLongForm<A, (TargetPriority << 1)>::type Inner;
646 typedef B<Inner> type;
650 struct LongModifierRule
656 template <class A, class S=typename LongModifierRule<A>::type>
657 struct StandardizeTagLongForm
659 typedef typename StandardizeTagLongForm<S>::type type;
664 struct StandardizeTagLongForm<A, A>
669 template <
class A,
template <
class>
class B>
670 struct LongModifierRule<B<A> >
672 typedef B<typename LongModifierRule<A>::type> type;
676 struct LongModifierRule<DefaultModifier<A> >
681 #define VIGRA_DROP_DATA_PREPARATION_MODIFIERS(SOURCE, TARGET) \
683 struct LongModifierRule<SOURCE > \
685 typedef TARGET type; \
688 VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Central<Sum>,
Sum)
689 VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Principal<Sum>,
Sum)
690 VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Whitened<Sum>,
Sum)
691 VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Principal<FlatScatterMatrix>, FlatScatterMatrix)
692 VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Whitened<FlatScatterMatrix>, FlatScatterMatrix)
693 VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Principal<ScatterMatrixEigensystem>, ScatterMatrixEigensystem)
694 VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Whitened<ScatterMatrixEigensystem>, ScatterMatrixEigensystem)
696 #undef VIGRA_DROP_DATA_PREPARATION_MODIFIERS
699 struct CheckSubstitutionFlag
701 static const bool value = (ModifierPriority<A>::value & SubstitutionMask) != 0;
704 template <
class A,
class B,
705 bool substitute=CheckSubstitutionFlag<A>::value>
706 struct SubstituteModifiers;
708 template <
class A,
class B>
709 struct SubstituteModifiers<A, B, false>
714 template <
class A,
template <
class>
class AA,
class B,
template <
class>
class BB>
715 struct SubstituteModifiers<AA<A>, BB<B>, true>
717 typedef AA<typename SubstituteModifiers<A, B>::type> type;
720 template <
class A,
class B,
template <
class>
class BB>
721 struct SubstituteModifiers<DefaultModifier<A>, BB<B>, true>
723 typedef BB<typename SubstituteModifiers<A, B>::type> type;
726 template <
class A,
template <
class>
class AA,
class B,
template <
class>
class BB>
727 struct SubstituteModifiers<AA<A>, BB<B>, false>
729 typedef BB<typename SubstituteModifiers<A, B>::type> type;
734 template <
class A,
class B>
735 struct TransferModifiers
737 typedef typename StandardizeTag<A>::type StdA;
738 typedef typename StandardizeTag<B>::type StdB;
739 typedef typename acc_detail::TagLongForm<StdA, acc_detail::MinPriority>::type AA;
740 typedef typename acc_detail::TagLongForm<StdB, acc_detail::MinPriority>::type BB;
741 typedef typename acc_detail::SubstituteModifiers<AA, BB>::type AB;
742 typedef typename acc_detail::StandardizeTagLongForm<AB>::type StdAB;
743 typedef typename StandardizeTag<StdAB>::type type;
746 template <
class A,
class HEAD,
class TAIL>
747 struct TransferModifiers<A, TypeList<HEAD, TAIL> >
749 typedef TypeList<typename TransferModifiers<A, HEAD>::type,
750 typename TransferModifiers<A, TAIL>::type> type;
754 struct TransferModifiers<A, void>
759 template <
class TargetTag,
class A=
typename TargetTag::Dependencies>
760 struct StandardizeDependencies
762 :
public StandardizeDependencies<TargetTag, typename A::type>
766 template <
class TargetTag,
class HEAD,
class TAIL>
767 struct StandardizeDependencies<TargetTag, TypeList<HEAD, TAIL> >
769 typedef typename StandardizeTag<TargetTag>::type Target;
770 typedef typename TransferModifiers<Target, TypeList<HEAD, TAIL> >::type type;
773 template <
class TargetTag>
774 struct StandardizeDependencies<TargetTag, void>
781 #endif // VIGRA_ACCUMULATOR_GRAMMAR_HXX