<commit_before>/**
 ** \file object/list-class.cc
 ** \brief Creation of the URBI object list.
 */

#include <boost/bind.hpp>

#include <libport/foreach.hh>
#include <libport/ufloat.hh>

#include <kernel/userver.hh>
#include <object/float-class.hh>
#include <object/list-class.hh>
#include <object/atom.hh>
#include <object/object.hh>
#include <object/primitives.hh>
#include <runner/runner.hh>

namespace object
{
  rObject list_class;

  /*----------------------------.
  | Primitives implementation.  |
  `----------------------------*/

  namespace
  {
    /// Concatenate two lists in place.
    /**
     * @return \a lhs
     */
    static rList
    PLUS_EQ(rList lhs, rList rhs)
    {
      // FIXME: If we use the following code, then a += a does not
      // end.
      //
      //      lhs->value_get().insert(lhs->value_get().end(),
      //			      rhs->value_get().begin(),
      //			      rhs->value_get().end());

      foreach (const rObject& o, rhs->value_get())
	lhs->value_get().push_back(o);

      return lhs;
    }

    /// Concatenate two lists.
    /**
     * @return A fresh list, concatenation of \a lhs and \a rhs
     */
    static rList
    PLUS(rList lhs, rList rhs)
    {
      // Copy lhs
      list_traits::type l(lhs->value_get());
      rList res = List::fresh(l);

      // Append rhs
      PLUS_EQ(res, rhs);
      return res;
    }

#define CHECK_NON_EMPTY							\
    List::value_type& ul = l->value_get();				\
    if (ul.empty ())							\
      throw PrimitiveError						\
	(__FUNCTION__, "operation cannot be applied onto empty list")

    /// Give the first element of \a l.
    static rObject
    front(rList l)
    {
      CHECK_NON_EMPTY;
      return ul.front();
    }

    /// Give the last element of \a l.
    static rObject
    back(rList l)
    {
      CHECK_NON_EMPTY;
      return ul.back();
    }

    /// Give \a l without the first element.
    static rList
    tail(rList l)
    {
      CHECK_NON_EMPTY;
      List::value_type res = ul;
      res.pop_front();
      return List::fresh(res);
    }

    /// Insert \a elt at the end of \a l
    static rList
    push_back(rList l, rObject elt)
    {
      l->value_get().push_back(elt);
      return l;
    }

    /// Insert \a elt at the front of \a l
    static rList
    push_front(rList l, rObject elt)
    {
      l->value_get().push_front(elt);
      return l;
    }

    /// Remove first element from \a l
    static rList
    pop_front(rList l)
    {
      CHECK_NON_EMPTY;
      ul.pop_front();
      return l;
    }

    static rList
    removeById(rList l, rObject elt)
    {
      List::value_type& under = l->value_get();
      List::value_type::iterator i = under.begin();
      while (i != under.end())
	if (*i == elt)
	  i = under.erase(i);
	else
	  ++i;
      return l;
    }

#undef CHECK_NON_EMPTY

    /// Clear \l
    static rList
    clear(rList l)
    {
      l->value_get().clear();
      return l;
    }

    /// Binary predicate used to sort lists.
    static bool
    compareListItems (runner::Runner&, rObject a, rObject b)
    {
      return is_true(urbi_call(::urbiserver->getCurrentRunner(),
                               a, SYMBOL(LT), b));
    }

    /// \brief Sort a list.
    /// If the list contains different kinds of elements,
    /// the order is not defined.
    /// \return New sorted list
    static rObject
    list_class_sort (runner::Runner& r, objects_type args)<commit_msg>Use provided runner instead of globally obtained oned.<commit_after>/**
 ** \file object/list-class.cc
 ** \brief Creation of the URBI object list.
 */

#include <boost/bind.hpp>

#include <libport/foreach.hh>
#include <libport/ufloat.hh>

#include <kernel/userver.hh>
#include <object/float-class.hh>
#include <object/list-class.hh>
#include <object/atom.hh>
#include <object/object.hh>
#include <object/primitives.hh>
#include <runner/runner.hh>

namespace object
{
  rObject list_class;

  /*----------------------------.
  | Primitives implementation.  |
  `----------------------------*/

  namespace
  {
    /// Concatenate two lists in place.
    /**
     * @return \a lhs
     */
    static rList
    PLUS_EQ(rList lhs, rList rhs)
    {
      // FIXME: If we use the following code, then a += a does not
      // end.
      //
      //      lhs->value_get().insert(lhs->value_get().end(),
      //			      rhs->value_get().begin(),
      //			      rhs->value_get().end());

      foreach (const rObject& o, rhs->value_get())
	lhs->value_get().push_back(o);

      return lhs;
    }

    /// Concatenate two lists.
    /**
     * @return A fresh list, concatenation of \a lhs and \a rhs
     */
    static rList
    PLUS(rList lhs, rList rhs)
    {
      // Copy lhs
      list_traits::type l(lhs->value_get());
      rList res = List::fresh(l);

      // Append rhs
      PLUS_EQ(res, rhs);
      return res;
    }

#define CHECK_NON_EMPTY							\
    List::value_type& ul = l->value_get();				\
    if (ul.empty ())							\
      throw PrimitiveError						\
	(__FUNCTION__, "operation cannot be applied onto empty list")

    /// Give the first element of \a l.
    static rObject
    front(rList l)
    {
      CHECK_NON_EMPTY;
      return ul.front();
    }

    /// Give the last element of \a l.
    static rObject
    back(rList l)
    {
      CHECK_NON_EMPTY;
      return ul.back();
    }

    /// Give \a l without the first element.
    static rList
    tail(rList l)
    {
      CHECK_NON_EMPTY;
      List::value_type res = ul;
      res.pop_front();
      return List::fresh(res);
    }

    /// Insert \a elt at the end of \a l
    static rList
    push_back(rList l, rObject elt)
    {
      l->value_get().push_back(elt);
      return l;
    }

    /// Insert \a elt at the front of \a l
    static rList
    push_front(rList l, rObject elt)
    {
      l->value_get().push_front(elt);
      return l;
    }

    /// Remove first element from \a l
    static rList
    pop_front(rList l)
    {
      CHECK_NON_EMPTY;
      ul.pop_front();
      return l;
    }

    static rList
    removeById(rList l, rObject elt)
    {
      List::value_type& under = l->value_get();
      List::value_type::iterator i = under.begin();
      while (i != under.end())
	if (*i == elt)
	  i = under.erase(i);
	else
	  ++i;
      return l;
    }

#undef CHECK_NON_EMPTY

    /// Clear \l
    static rList
    clear(rList l)
    {
      l->value_get().clear();
      return l;
    }

    /// Binary predicate used to sort lists.
    static bool
    compareListItems (runner::Runner& r, rObject a, rObject b)
    {
      return is_true(urbi_call(r, a, SYMBOL(LT), b));
    }

    /// \brief Sort a list.
    /// If the list contains different kinds of elements,
    /// the order is not defined.
    /// \return New sorted list
    static rObject
    list_class_sort (runner::Runner& r, objects_type args)
{'fraction_non_alphanumeric': 0.14665886825559293, 'fraction_numerical': 0.0, 'mean_word_length': 1.8739495798319328, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 48, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7555495', 'n_tokens_mistral': 2382, 'n_tokens_neox': 2306, 'n_words': 615}