lumiera_/tests/12metaprogramming.tests
Ichthyostega 412abbace2 clean-up: validate use of variadic seq with tuples and generators
Most of the type-list and type-sequence related eccosystem can be
just switched over, after having added the conversion variants for
the new-style variadic type sequences

Again this was used as opportunity to improve readability of related tests
2025-06-03 16:14:13 +02:00

560 lines
18 KiB
Text

TESTING "Metaprogramming facilities and techniques" ./test-suite --group=common
TEST "casting or converting access helper" AccessCasted_test <<END
out-lit: can_downcast<B,D> = 1
out-lit: can_downcast<B*,D*> = 1
out-lit: can_downcast<B&,D&> = 1
out-lit: can_downcast<B&,D*> = 0
out-lit: can_downcast<B*,D&> = 0
out-lit: can_downcast<B*&,D*&> = 1
out-lit: can_downcast<D*&,D*&> = 1
out-lit: can_downcast<D*,E*> = 1
out-lit: can_downcast<E*,F*> = 1
out-lit: has_RTTI<D*> = 0
out-lit: has_RTTI<E*> = 1
out-lit: has_RTTI<F*> = 1
out-lit: is_convertible<D,D&> = 0
out-lit: is_convertible<D&,D> = 1
out-lit: can_use_dynamic_downcast<D,D&> = 0
out-lit: can_use_conversion<D,D&> = 0
out-lit: can_use_dynamic_downcast<B*,D*> = 0
out-lit: can_use_conversion<D*,B*> = 1
out-lit: can_use_dynamic_downcast<D*&,D*&> = 0
out-lit: can_use_conversion<D*&,D*&> = 1
out-lit: can_use_conversion<D*,E*> = 0
out-lit: can_use_dynamic_downcast<D*&,E*> = 0
out-lit: can_use_conversion<E*,F*> = 0
out-lit: can_use_dynamic_downcast<E*,F*> = 1
out-lit: === standard case: References ===
out: Access\(D as D&\) .+D.. adr=╲\w{8} ↗«D»
out: Access\(D& as D&\) .+D.. adr=╲\w{8} ↗«D»
out-lit: === build a value object ===
out: Access.D as D. .+D.. adr=╲\w{8} ↗«D»
out: Access.D& as D. .+D.. adr=╲\w{8} ↗«D»
out: Access.D&& as D. .+D.. adr=╲\w{8} ↗«D»
out-lit: === take a pointer ===
out: Access.D as D\*. .+╲\w{8}
out: Access.D& as D\*. .+╲\w{8}
out-lit: === dereference a pointer ===
out: Access.D\* as D&. .+D.. adr=╲\w{8} ↗«D»
out: Access.D\* as D. .+D.. adr=╲\w{8} ↗«D»
out: Access.D\*&& as D. .+D.. adr=╲\w{8} ↗«D»
out-lit: === const correctness ===
out: Access.D as D const&. .+D.. adr=╲\w{8} ↗«D»
out: Access.D& as D const&. .+D.. adr=╲\w{8} ↗«D»
out: Access.D as const D. .+D.. adr=╲\w{8} ↗«D»
out: Access.D& as const D. .+D.. adr=╲\w{8} ↗«D»
out: Access.D as const D\*. .+╲\w{8}
out: Access.D& as const D\*. .+╲\w{8}
out: Access.D\* as D const&. .+D.. adr=╲\w{8} ↗«D»
out: Access.D\* as const D. .+D.. adr=╲\w{8} ↗«D»
out: Access.const D as D const&. .+D.. adr=╲\w{8} ↗«D»
out: Access.D const& as D const&. .+D.. adr=╲\w{8} ↗«D»
out: Access.const D as const D. .+D.. adr=╲\w{8} ↗«D»
out: Access.D const& as const D. .+D.. adr=╲\w{8} ↗«D»
out: Access.const D as const D\*..+╲\w{8}
out: Access.D const& as const D\*..+╲\w{8}
out: Access.const D\* as D const&..+D.. adr=╲\w{8} ↗«D»
out: Access.const D\* as const D. .+D.. adr=╲\w{8} ↗«D»
out: Access.D const& as D. .+D.. adr=╲\w{8} ↗«D»
out: Access.D const&& as D. .+D.. adr=╲\w{8} ↗«D»
out-lit: === work cases: actual conversions ===
out: Access.B& as B&. .+B.. adr=╲\w{8} ↗«B»
out: Access.D& as B&. .+B.. adr=╲\w{8} ↗«B»
out: Access.B\* as B\*. .+╲\w{8}
out: Access.D\* as B\*. .+╲\w{8}
out: Access.D& as B\*. .+╲\w{8}
out: Access.D\* as B&. .+B.. adr=╲\w{8} ↗«B»
out: Access.B\*& as B\*&. .+╲\w{8}
out: Access.D\*& as D\*&. .+╲\w{8}
out: Access.D& as const B\*. .+╲\w{8}
out: Access.D\* as B const&. .+B.. adr=╲\w{8} ↗«B»
out: Access.D const& as const B\*..+╲\w{8}
out: Access.const D\* as B const&..+B.. adr=╲\w{8} ↗«B»
out: Access.E\(F\)& as F&. .+F.. adr=╲\w{8} ↗«F»
out: Access.E\(F\)\* as F\*. .+╲\w{8}
out: Access.E\(F\)\* as F&. .+F.. adr=╲\w{8} ↗«F»
out: Access.E\(F\)& as F\*. .+╲\w{8}
out: Access.F\\* as X\*. .+╲\w{8}
out: Access.X\(F\)\* as X\*. .+╲\w{8}
out: Access.F\* as B&. .+B.. adr=╲\w{8} ↗«B»
out: Access.F\* as E&*. .+E.. adr=╲\w{8} ↗«F»
out-lit: Access(int as double) --->2
out-lit: Access(float as long) --->3
return: 0
END
TEST "Duck typing support" DuckDetector_test <<END
out: HasNested_Core<PropperGander> : Yes
out: HasNested_Core<Propaganda> : No
out: HasMember_honk<PropperGander> : Yes
out: HasMember_honk<Propaganda> : Yes
out: HasFunSig_honk<PropperGander> : Yes
out: HasFunSig_honk<Propaganda> : No
return: 0
END
TEST "Duck detect extension points" DuckDetectorExtension_test <<END
return: 0
END
TEST "functional closure" FunctionClosure_test <<END
out-lit: List1 :-<1>-<2>-<3>-
out-lit: List2 :-<5>-<6>-<7>-
out-lit: Args :-<5>-<9>-
out-lit: NewArgs :-<1>-<5>-<9>-
out-lit: :
out-lit: : ---Apply---
out-lit: tup0 :«tuple<>»──()
out-lit: tup1 :«tuple<int>»──(11)
out-lit: tup2 :«tuple<int, int>»──(11,12)
out-lit: tup3 :«tuple<int, int, int>»──(11,12,13)
out-lit: :
out-lit: : ---Bind----
return: 0
END
TEST "functional composition" FunctionComposition_test <<END
return: 0
END
TEST "function type erasure" FunctionErasure_test <<END
return: 0
END
TEST "function signature trait" FunctionSignature_test <<END
return: 0
END
TEST "member function late binding" LateBindInstance_test <<END
return: 0
END
TEST "metaprogramming helpers" MetaUtils_test <<END
return: 0
END
TEST "Lumiera Iterator Concept" IterAdapter_test 20 <<END
out-lit: ::20::19::18::17::16::15::14::13::12::11::10::9::8::7::6::5::4::3::2::1
out-lit: ::20::19::18::17::16::15::14::13::12::11::10::9::8::7::6::5::4::3::2::1
out-lit: ++21++22++23++24++25++26++27++28++29++30++31++32++33++34++35++36++37++38++39
out-lit: ::0::1::2::3::4::5::6::7::8::9::10::11::12::13::14::15::16::17::18::19
out-lit: ::0::1::2::3::4::5::6::7::8::9::10::11::12::13::14::15::16::17::18::19
return: 0
END
TEST "Lumiera Iterator Adapter for STL" IterAdapterSTL_test <<END
out-lit: -----filter-distinct-values---vector<int>
out-lit: iter::eachDistinct
out-lit: iter::eachDistinct::1
out-lit: iter::eachDistinct::1::2::3::1
out-lit: iter::eachDistinct::1::2::3::1
out-lit: -----iterateMapKeyVal---map<int, int>
out-lit: iter::eachKey::0::1::2::3::4::5::6::7::8::9
out-lit: iter::eachKey::0::1::2::3::4::5::6::7::8::9
out-lit: iter::eachVal::0::2::4::6::8::10::12::14::16::18
out-lit: iter::eachVal::0::2::4::6::8::10::12::14::16::18
out-lit: iter::eachDistinctKey::0::1::2::3::4::5::6::7::8::9
out-lit: -----iterateMapKeyVal---unordered_map<int, int>
out: iter::eachKey::.::.::.::.::.::.::.::.::.::.
out: iter::eachVal::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+
out: iter::eachDistinctKey::.::.::.::.::.::.::.::.::.::.
out-lit: -----iterateMapKeyVal---multimap<int, int>
out-lit: iter::eachKey::0::0::0::0::0::0::0::0::0::0::1::1::1::1::1::1::1::1::1::2::2::2::2::2::2::2::2::3::3::3::3::3::3::3::4::4::4::4::4::4::5::5::5::5::5::6::6::6::6::7::7::7::8::8::9
out-lit: iter::eachKey::0::0::0::0::0::0::0::0::0::0::1::1::1::1::1::1::1::1::1::2::2::2::2::2::2::2::2::3::3::3::3::3::3::3::4::4::4::4::4::4::5::5::5::5::5::6::6::6::6::7::7::7::8::8::9
out-lit: iter::eachVal::10::9::8::7::6::5::4::3::2::1::9::8::7::6::5::4::3::2::1::8::7::6::5::4::3::2::1::7::6::5::4::3::2::1::6::5::4::3::2::1::5::4::3::2::1::4::3::2::1::3::2::1::2::1::1
out-lit: iter::eachVal::10::9::8::7::6::5::4::3::2::1::9::8::7::6::5::4::3::2::1::8::7::6::5::4::3::2::1::7::6::5::4::3::2::1::6::5::4::3::2::1::5::4::3::2::1::4::3::2::1::3::2::1::2::1::1
out-lit: iter::eachDistinctKey::0::1::2::3::4::5::6::7::8::9
out-lit: -----iterateMapKeyVal---unordered_multimap<int, int>
out: iter::eachKey::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.::.
out: iter::eachVal::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+
out: iter::eachDistinctKey::.::.::.::.::.::.::.::.::.::.
out-lit: -----iterateValues4Key---multimap<int, int>
out-lit: iter::eachValForKey::10::9::8::7::6::5::4::3::2::1
out-lit: -----iterateValues4Key---unordered_multimap<int, int>
out: iter::eachValForKey::.+::.+::.+::.+::.+::.+::.+::.+::.+::.+
out-lit: snapshot-0-1-2-3-4-5-6-7-8-9
out-lit: snapshot-0-1-2-3-4-5-6-7-8-9
out-lit: snapshot-22-44
return: 0
END
TEST "Lumiera Iterator Tools" IterTools_test 20 <<END
out-lit: ::20::19::18::17::16::15::14::13::12::11::10::9::8::7::6::5::4::3::2::1
out-lit: ::20::19::18::17::16::15::14::13::12::11::10::9::8::7::6::5::4::3::2::1
out-lit: ::20::18::16::14::12::10::8::6::4::2
out-lit: ::19::17::15::13::11::9::7::5::3::1
out-lit: ::17::16::15::14::13::12::11::10::9::8::7::6::5::4::3::2::1
out-lit: ::16::14::12::10::8::6::4::2
out-lit: ::17::15::13::11::9::7::5::3::1
out-lit: ::12::18::24::30::36::42::48::54
out-lit: ::13::17::19::23::25::29::31::35::37::41::43::47::49::53::55::59
out-lit: ::20::19::18::17::16::15::14::13::12::11::10::9::8::7::6::5::4::3::2::1
out-lit: ::-20::-19::-18::-17::-16::-15::-14::-13::-12::-11::-10::-9::-8::-7::-6::-5::-4::-3::-2::-1
out-lit: ::22::21::20::19::18::17::16::15::14::13::12::11::10::9::8::7::6::5::4::3
return: 0
END
TEST "Lumiera state-core iteration" IterCoreAdapter_test 20 <<END
return: 0
END
TEST "forward/backward iterator" IterCursor_test 20 <<END
return: 0
END
TEST "index-based iterator" IndexIter_test 20 <<END
return: 0
END
TEST "Iterable data source" IterSource_test 13 <<END
out: ::13::12::11::10::9::8::7::6::5::4::3::2::1
out: ::.............::............::...........::..........::.........::........::.......::......::.....::....::...::..::.$
out-lit: ::3s250ms::3s::2s750ms::2s500ms::2s250ms::2s::1s750ms::1s500ms::1s250ms::1s::750ms::500ms::250ms
out: (::X...........){13}$
out: (::.+s){13}$
out: (::X...........){13}$
out: (::.+s){13}$
out: distinct_keys::0::1::2::3::4::5::6::7::8::9::10::11::12
out: values_4_key(::[0-9]{1,2})+
out: distinct_keys(::[0-9]{1,2}){13}
out: values_4_key(::[0-9]{1,2})+
return: 0
END
TEST "Iterator tree exploration" IterExplorer_test <<END
out-lit: 4-3-2-1
out: Search in random tree: toFind = .....
out: Protocol of the search: .+\-.+\-.+\-.+\-.+
return: 0
END
TEST "Stack-like iterator" IterStack_test <<END
return: 0
END
TEST "Queue-like iterator" IterQueue_test <<END
return: 0
END
TEST "Tuple-zipped iterators" IterZip_test <<END
return: 0
END
TEST "Iterable type detection" IterableClassification_test <<END
out: can_STL_ForEach<LongVector> : Yes
out: can_STL_ForEach<TimeSet> : Yes
out: can_STL_ForEach<CharMap> : Yes
out: can_STL_ForEach<BoolList> : Yes
out: can_STL_ForEach<ShortDeque> : Yes
out: can_STL_ForEach<CustomCont> : Yes
out: can_STL_ForEach<ForwardRangeIter> : No
out: can_STL_ForEach<TransformedForwardIter> : No
out: can_STL_ForEach<FilteredForwardIter> : No
out: can_STL_ForEach<CustomForwardIter> : No
out: can_IterForEach<LongVector> : No
out: can_IterForEach<TimeSet> : No
out: can_IterForEach<CharMap> : No
out: can_IterForEach<BoolList> : No
out: can_IterForEach<ShortDeque> : No
out: can_IterForEach<CustomCont> : No
out: can_IterForEach<ForwardRangeIter> : Yes
out: can_IterForEach<TransformedForwardIter> : Yes
out: can_IterForEach<FilteredForwardIter> : Yes
out: can_IterForEach<CustomForwardIter> : Yes
return: 0
END
TEST "Linked iterable elements" LinkedElements_test <<END
return: 0
END
TEST "Polymorphic value objects" PolymorphicValue_test <<END
return: 0
END
TEST "Variadic template diagnostics" TestHelperVariadic_test <<END
out-lit: --no-arg--
out-lit: :.
out-lit: --reference--
out: .+#1.+ Type: double& .+Adr╲.+
out-lit: :.
out-lit: --value--
out: .+#1.+ Type: double && .+Adr╲.+
out-lit: :.
out-lit: --two values--
out: .+#2.+ Type: char \[4\] const& .+Adr╲.+
out: .+#1.+ Type: long && .+Adr╲.+
out-lit: :.
out-lit: --references--
out: .+#3.+ Type: double& .+Adr╲.+
out: .+#2.+ Type: double const& .+Adr╲.+
out: .+#1.+ Type: double && .+Adr╲.+
out-lit: :.
out-lit: --baseclass--
out: .+#1.+ Type: Interface const& .+Adr╲.+
out-lit: :.
return: 0
END
TEST "Helper to show demangled C++ names" TypeDemangling_test <<END
out: .+lib.meta.test.Space.+Outer.+Inner
out-lit: lib::meta::test::Space const* (*)(lib::meta::test::Outer<lib::meta::test::Space>::Inner const&&)
return: 0
END
TEST "Helper for human readable type display" TypeDisplay_test <<END
return: 0
END
TEST "Loki Type-List" TypeList_test <<END
out-lit: - 21 -- 13 -- 8 -- 5 -- 3 -- 2 -- 1 -- The End -
return: 0
END
TEST "Simple Type-List utilities" TypeListUtil_test <<END
return: 0
END
TEST "Type driven class generation" TypeListGenerator_test <<END
out: ctor DoIt<Block<13> >
out: ctor DoIt<Block< 8> >
out: ctor DoIt<Block< 5> >
out: ctor DoIt<Block< 3> >
out: ctor DoIt<Block< 2> >
out: ctor DoIt<Block< 1> >
out: devouring__Block< 2>__
out: devouring__Block< 5>__
out: devouring__Block<13>__
out: gulp!
out: dtor DoIt<Block< 1> >
out: dtor DoIt<Block< 2> >
out: dtor DoIt<Block< 3> >
out: dtor DoIt<Block< 5> >
out: dtor DoIt<Block< 8> >
out: dtor DoIt<Block<13> >
return: 0
END
TEST "Typelist manipulation" TypeListManip_test <<END
out-lit: List1 :-<1>-<2>-<3>-
out-lit: List2 :-<5>-<6>-<7>-
return: 0
END
TEST "type sequence manipulation" TypeSeqManip_test <<END
return: 0
END
TEST "tuple value pre-binding closure" TupleClosure_test <<END
return: 0
END
TEST "tuple metaprogramming helpers" TupleHelper_test <<END
out-lit: L1 :-<1>-<3>-<5>-
out-lit: L2 :-<2>-<4>-
out-lit: L3 :-<7>-
out-lit: Tup1 :TUPLE-<1>-<3>-<5>-
out-lit: Tup1() :«tuple<Num<1>, Num<3>, Num<5> >»──((1),(3),(5))
out-lit: tup1x :«tuple<Num<1>, Num<3>, Num<5> >»──({11},(3),{55})
out-lit: «tuple<Num<1>, Num<3>, Num<5> >»──((1),(3),(5))
out-lit: «tuple<int, Num<1>, Num<3>, Num<5> >»──(22,{11},{33},(5))
out-lit: «tuple<>»──()
out: sizeof. tuple<Num<1>, Num<3>, Num<5> > . = 12
out: sizeof. tuple<int, Num<1>, Num<3>, Num<5> > . = 16
out-lit: sizeof( tuple<> ) = 1
out-lit: sizeof( tuple<> ) = 1
return: 0
END
TEST "tuple initialisation from GenNode" TupleRecordInit_test <<END
out: Rec...GenNode.+DataCap.«string».lalü, GenNode.+DataCap.«int».42
out: Rec...GenNode.+DataCap.«string».lalü, GenNode.+DataCap.«string».lala, GenNode.+DataCap.«int».12, GenNode.+DataCap.«int».34, GenNode.+DataCap.«double».5.6, GenNode.+DataCap.«Time».0:09:08.007
out-lit: «tuple<string, int>»──(lalü,42)
out-lit: «tuple<idi::EntryID<long>, Symbol, int, long, double, Duration>»──(ID<long>-lal,lala,12,34,5.6,≺548s7ms≻)
return: 0
END
TEST "variadic type manipulations" VariadicHelper_test <<END
return: 0
END
TEST "variadic argument manipulation" VariadicArgumentPicker_test <<END
out: 4╎N<1>──.─┼N<2>──.─┼N<3>──.─┼N<3>──.─┤
out: 4╎N<0>──.─┼N<1>──.─┼N<2>──.─┼N<3>──.─┤
out: 4╎N<3>──.─┼N<2>──.─┼N<1>──.─┼N<0>──.─┤
out: 2╎N<1>──.─┼N<0>──.─┤
out: 2╎N<2>──.─┼N<3>──.─┤
return: 0
END
TEST "Typelist combinations generator" GeneratorCombinations_test <<END
out-lit: Cartesian :
out-lit: +---<1>-<2>-+
out-lit: +---<1>-<4>-+
out-lit: +---<1>-<6>-+
out-lit: +---<3>-<2>-+
out-lit: +---<3>-<4>-+
out-lit: +---<3>-<6>-+
out-lit: +---<5>-<2>-+
out-lit: +---<5>-<4>-+
out-lit: +---<5>-<6>-+-
out-lit: All-Test-Combinations--<12>-<14>-<16>-<32>-<34>-<36>-<52>-<54>-<56>-|
return: 0
END
TEST "Type-based contexts" TypedCounter_test <<END
return: 0
END
TEST "Type-based family member IDs" TypedFamilyMemberID_test <<END
return: 0
END
TEST "for-each operations" UtilForeach_test 10 <<END
out: ---:check_foreach_plain
out: :10:9:8:7:6:5:4:3:2:1
out: :10$
out: ---:check_foreach_plain
out: :10:9:8:7:6:5:4:3:2:1
out: :10$
out: ---:check_foreach_bind
out: :20:19:18:17:16:15:14:13:12:11
out: :20$
out: :20:18:16:14:12:10:8:6:4:2
out: :20$
out: ---:check_foreach_bind
out: :20:19:18:17:16:15:14:13:12:11
out: :20$
out: :20:18:16:14:12:10:8:6:4:2
out: :20$
out: ---:check_foreach_bind_const
out: :20:19:18:17:16:15:14:13:12:11
out: :20$
out: :20:18:16:14:12:10:8:6:4:2
out: :20$
out: :20:38:54:68:80:90:98:104:108:110
out: :130:148:164:178:190:200:208:214:218:220
out: :240
out: ---:check_foreach_memFun
out: :10:19:27:34:40:45:49:52:54:55
out: :10$
out: :10:19:27:34:40:45:49:52:54:55
out: :65:74:82:89:95:100:104:107:109:110
out: :120
out: sum=120
out: ---:check_foreach_memFun
out: :10:19:27:34:40:45:49:52:54:55
out: :10$
out: :10:19:27:34:40:45:49:52:54:55
out: :65:74:82:89:95:100:104:107:109:110
out: :120
out: sum=120
out: ---:check_foreach_lambda
out: ---:check_existence_quant
out: ---:assign_to_input
out: :20:19:18:17:16:15:14:13:12:11
out: :30:29:28:27:26:25:24:23:22:21
out: :40:39:38:37:36:35:34:33:32:31
out: :50:49:48:47:46:45:44:43:42:41
out: :60
out: :70
out: :80:59:58:57:56:55:54:53:52:51
out: :90:69:68:67:66:65:64:63:62:61
out: :100$
out: ---:assign_to_var
out: :90:149:207:264:320:375:429:482:534:585
out: :675:734:792:849:905:960:1014:1067:1119:1170
out: :1260:1319:1377:1434:1490:1545:1599:1652:1704:1755
out: sum=1755
out: :90:149:207:264:320:375:429:482:534:585
out: :675:734:792:849:905:960:1014:1067:1119:1170
out: :1260:1319:1377:1434:1490:1545:1599:1652:1704:1755
out: sum=1755
out: :90
out: :180
out: :270
out: sum=270
out: ---:assign_to_input
out: :20:19:18:17:16:15:14:13:12:11
out: :30:29:28:27:26:25:24:23:22:21
out: :40:39:38:37:36:35:34:33:32:31
out: :50:49:48:47:46:45:44:43:42:41
out: :60
out: :70
out: :80:59:58:57:56:55:54:53:52:51
out: :90:69:68:67:66:65:64:63:62:61
out: :100$
out: ---:assign_to_var
out: :90:149:207:264:320:375:429:482:534:585
out: :675:734:792:849:905:960:1014:1067:1119:1170
out: :1260:1319:1377:1434:1490:1545:1599:1652:1704:1755
out: sum=1755
out: :90:149:207:264:320:375:429:482:534:585
out: :675:734:792:849:905:960:1014:1067:1119:1170
out: :1260:1319:1377:1434:1490:1545:1599:1652:1704:1755
out: sum=1755
out: :90
out: :180
out: :270
out: sum=270
out: ---:wrapped_container_passing
out: :10:9:8:7:6:5:4:3:2:1
out: :-20:-21:-22:-23:-24:-25:-26:-27:-28:-29
out: ---:check_invoke_on_each
out: :0:1:2:3:4:5
out: :0$
out: :0:1$
out: :0:1:2:3:4:5
out: :0$
out: :0:1$
return: 0
END
TEST "Virtual copying of opaque objects" VirtualCopySupport_test <<END
return: 0
END