@function __base-uniq($list, $iteratee: '__identity', $guard: null) {
    $result: ();

    $iteratee: if(__is-iteratee-call($list, $iteratee, $guard), '__identity', $iteratee);

    @each $item in $list {
        $iteration: __exec($iteratee, $item);

        @if type-of($iteration) == 'list' {
            $iteration: inspect($iteration);
        }

        $result: map-merge($result, (
            $iteration: $item
        ));
    }

    @return map-values($result);
}


@function __uniq($list, $iteratee: '__identity', $this-arg: null) {
    $length: if($list, length($list), 0);

    @if __is-falsey($length) {
        @return ();
    }

    @if __is-iteratee-call($list, $iteratee, $this-arg) {
        $iteratee: '__identity';
        $this-arg: null;
    }

    $iteratee: __get-callback($iteratee, $this-arg, 3);

    @return __base-uniq($list, $iteratee);
}


/// Creates a duplicate-value-free version of a list.
/// 
/// If an iteratee function is provided it
/// is invoked for each value in the list to generate the criterion by which
/// uniqueness is computed. The `$iteratee` is bound to `$this-arg` and invoked
/// with three arguments; (value, index, list).
/// 
/// If a property name is provided for `$predicate` the created `_property`
/// style callback returns the property value of the given element.
/// 
/// If a value is also provided for `$this-arg` the created `_matches-property`
/// style callback returns `true` for elements that have a matching property
/// value, else `false`.
/// 
/// If a map is provided for `$predicate` the created `_matches` style
/// callback returns `true` for elements that have the properties of the given
/// object, else `false`.
///
///
/// @access public
/// @group List
/// @param {List} $list The list to inspect.
/// @param {Function|Map|string} $iteratee [_identity] - The function invoked per iteration.
/// @param {*} $this-arg [null] - The `_this` binding of `$iteratee`.
/// @returns {List} Returns the new duplicate-value-free list.
/// @example scss
/// $foo: _uniq((1, 2, 1));
/// // => (1, 2)
///
/// // using an iteratee function
/// $foo: _uniq((1, 2.5, 1.5, 2), floor);
/// // => (1, 2.5)
/// 
/// // using the `_property` callback shorthand
/// $foo: _uniq((( 'x': 1 ), ( 'x': 2 ), ( 'x': 1 )), 'x');
/// // => (( 'x': 1 ), ( 'x': 2 ))

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


/// @alias _uniq

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