# This file implements the following set operators: # (elem) is an element of (ASCII) # ∈ is an element of # ∉ is NOT an element of # (cont) contains (ASCII) # ∋ contains # ∌ does NOT contain proto sub infix:<(elem)>($, $, *% --> Bool:D) is pure {*} multi sub infix:<(elem)>(Str:D $a, Map:D \b --> Bool:D) { nqp::hllbool( nqp::istrue( nqp::elems(my \storage := nqp::getattr(nqp::decont(b),Map,'$!storage')) && nqp::if( nqp::istype(b,Hash::Object), nqp::getattr( # object hash nqp::ifnull( nqp::atkey(storage,$a.WHICH), BEGIN # provide virtual value False # did not exist nqp::p6bindattrinvres(nqp::create(Pair),Pair,'$!value',False) ), Pair, '$!value' ), nqp::atkey(storage,$a) # normal hash ) ) ) } multi sub infix:<(elem)>(Any \a, Map:D \b --> Bool:D) { nqp::hllbool( nqp::istrue( nqp::elems( # haz a haystack my \storage := nqp::getattr(nqp::decont(b),Map,'$!storage') ) && nqp::istype(b,Hash::Object) && nqp::getattr( nqp::ifnull( nqp::atkey(storage,a.WHICH), # exists BEGIN # provide virtual value False # did not exist nqp::p6bindattrinvres(nqp::create(Pair),Pair,'$!value',False) ), Pair, '$!value' ) ) ) } multi sub infix:<(elem)>(Str:D $a, array[str] \b --> Bool:D) { my int $i = -1; nqp::while( nqp::islt_i(++$i,nqp::elems(b)) && nqp::isne_s($a,nqp::atpos_s(b,$i)), nqp::null ); nqp::hllbool(nqp::islt_i($i,nqp::elems(b))) } multi sub infix:<(elem)>(Int:D $a, array[int] \b --> Bool:D) { my int $i = -1; nqp::while( nqp::islt_i(++$i,nqp::elems(b)) && nqp::isne_i($a,nqp::atpos_i(b,$i)), nqp::null ); nqp::hllbool(nqp::islt_i($i,nqp::elems(b))) } multi sub infix:<(elem)>(Int:D $a, Range:D \b --> Bool:D) { b.is-int ?? b.ACCEPTS($a) !! $a (elem) b.iterator } multi sub infix:<(elem)>(Any \a, Iterable:D \b --> Bool:D) { a (elem) b.iterator } multi sub infix:<(elem)>(Any \a, Iterator:D \b --> Bool:D) { nqp::if( b.is-lazy, Any.fail-iterator-cannot-be-lazy('(elem)',''), nqp::stmts( (my str $needle = a.WHICH), nqp::until( nqp::eqaddr( (my \pulled := nqp::decont(b.pull-one)), IterationEnd ), nqp::if( nqp::iseq_s($needle,pulled.WHICH), return True ) ), False ) ) } multi sub infix:<(elem)>(Any \a, QuantHash:D $b --> Bool:D) { nqp::hllbool( (my \elems := $b.RAW-HASH) ?? nqp::existskey(elems,a.WHICH) !! 0 ) } multi sub infix:<(elem)>(Any, Failure:D $b) { $b.throw } multi sub infix:<(elem)>(Failure:D $a, Any) { $a.throw } multi sub infix:<(elem)>(Any \a, Any \b) { a (elem) b.Set } # U+2208 ELEMENT OF my constant &infix:<∈> := &infix:<(elem)>; # U+220A SMALL ELEMENT OF my constant &infix:<∊> := &infix:<(elem)>; # U+2209 NOT AN ELEMENT OF proto sub infix:<∉>($, $, *%) is pure {*} multi sub infix:<∉>(\a, \b --> Bool:D) { not a (elem) b } proto sub infix:<(cont)>($, $, *%) is pure {*} multi sub infix:<(cont)>(\a, \b --> Bool:D) { b (elem) a } # U+220B CONTAINS AS MEMBER my constant &infix:<∋> = &infix:<(cont)>; # U+220D SMALL CONTAINS AS MEMBER my constant &infix:<∍> = &infix:<(cont)>; # U+220C DOES NOT CONTAIN AS MEMBER proto sub infix:<∌>($, $, *%) is pure {*} multi sub infix:<∌>(\a, \b --> Bool:D) { not b (elem) a } # vim: expandtab shiftwidth=4