@function __base-matches-function-1($map, $args...) {
    $value: __this('value');
    $key: __this('key');

    @return __is-truthy($map)
    and map-has-key($map, $key)
    and $value == __get($map, $key);
}


@function __base-matches-function-2($map, $args...) {
    @return __base-is-match(
        $map,
        __this('props'),
        __this('values'),
        __this('strict-compare-flags'));
}


@function __base-matches($source, $is-cloned: false) {
    $props: map-keys($source);
    $length: length($props);
    $_: __scope();

    @if ($length == 1) {
        $key: nth($props, 1);
        $value: __get($source, $key);
        $_: __this('key', $key);
        $_: __this('value', $value);

        @if (__is-strict-comparable($value)) {
            $result: __bind('__base-matches-function-1');
            $_: __scope(false);

            @return $result;
        }
    }

    $values: (); // list
    $strict-compare-flags: (); // list

    @while ($length > 0) {
        $value: __get($source, nth($props, $length));
        $values: __set($values, $length, $value);
        $strict-compare-flags: __set($strict-compare-flags, $length, __is-strict-comparable($value));
        $length: $length - 1;
    }

    $values: __to-list($values);
    $strict-compare-flags: __to-list($strict-compare-flags);
    $_: __this('props', $props);
    $_: __this('values', $values);
    $_: __this('strict-compare-flags', $strict-compare-flags);
    $result: __bind('__base-matches-function-2');
    $_: __scope(false);

    @return $result;
}


@function __matches($source) {
    @return __base-matches($source, true);
}


/// Creates a function which performs a deep comparison between a given map
/// and `source`, returning `true` if the given map has equivalent property
/// values, else `false`.
///
///
/// @access public
/// @group Utility
/// @param {Map} $source The map of property values to match.
/// @returns {Function} Returns the new function.
/// @example scss
/// $users: (
///   ( 'user': 'barney', 'age': 36, 'active': true ),
///   ( 'user': 'fred',   'age': 40, 'active': false )
/// );
/// $foo: _filter($users, _matches(( 'age': 40, 'active': false )));
/// // => (( 'user': 'fred', 'age': 40, 'active': false ),)

@function _matches($args...) {
    @return call(get-function('__matches'), $args...);
}
