@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...);
}
