@normalize_types_one_arg<EOL><INDENT>def __and__(self, other):<DEDENT>
if type(other) is ValueSet:<EOL><INDENT>if self.identical(other):<EOL><INDENT>return self.copy()<EOL><DEDENT><DEDENT>if BoolResult.is_true(other == <NUM_LIT:0>):<EOL><INDENT>return StridedInterval(bits=self.bits, stride=<NUM_LIT:0>, lower_bound=<NUM_LIT:0>, upper_bound=<NUM_LIT:0>)<EOL><DEDENT>if BoolResult.is_true(other < <NUM_LIT>):<EOL><INDENT>ret = None<EOL>for region, si in self._regions.items():<EOL><INDENT>r = si.__and__(other)<EOL>ret = r if ret is None else ret.union(r)<EOL><DEDENT>return ret<EOL><DEDENT>else:<EOL><INDENT>new_vs = self.copy()<EOL>for region, si in self._regions.items():<EOL><INDENT>r = si.__and__(other)<EOL>new_vs._regions[region] = r<EOL><DEDENT>return new_vs<EOL><DEDENT>
Binary operation: and

Note that even if `other` is a ValueSet object, it will be treated as a StridedInterval as well. Doing & between
two pointers that are not the same do not make sense.

:param other: The other operand
:return: A ValueSet as the result
:rtype: ValueSet