<commit_before>/**
 ** \file libport/shared-ptr.hxx
 ** \brief Implementation of libport::boost_shared_ptr.
 **/

#ifndef LIBPORT_BOOST_SHARED_PTR_HXX
# define LIBPORT_BOOST_SHARED_PTR_HXX

# include <libport/shared-ptr.hh>

namespace libport
{

  /*-----------------.
  | Ctors and dtor.  |
  `-----------------*/

  template <typename T, bool I>
  template <typename U>
  shared_ptr<T,I>::shared_ptr (const shared_ptr<U,I>& other)
    : super_type (other)
  {
  }

  template <typename T, bool I>
  shared_ptr<T,I>::shared_ptr (const shared_ptr<T,I>& other)
    : super_type (other)
  {
  }

  template <typename T, bool I>
  shared_ptr<T,I>::shared_ptr (T* p)
    : super_type (p)
  {
  }

  template <typename T, bool I>
  shared_ptr<T,I>::~shared_ptr ()
  {
  }


  /*---------------------.
  | Equality operators.  |
  `---------------------*/

  template <typename T, bool I>
  bool
  shared_ptr<T,I>::operator== (const T* other) const
  {
    return this->get () == other;
  }

  template <typename T, bool I>
  bool
  shared_ptr<T,I>::operator!= (const T* other) const
  {
    return !(*this == other);
  }


  /*--------.
  | Casts.  |
  `--------*/

  template <typename T, bool I>
  template <typename U>
  shared_ptr<U>
  shared_ptr<T,I>::unsafe_cast () const
  {
    shared_ptr<U> res;
    (boost::dynamic_pointer_cast<U, element_type> (*this)).swap (res);
    return res;
  }

  template <typename T, bool I>
  template <typename U>
  shared_ptr<U>
  shared_ptr<T,I>::cast () const
  {
    if (!this->get () || !this->is_a<U> ())
      throw std::bad_cast ();
    return unsafe_cast<U> ();
  }

  template <typename T, bool I>
  template <typename U>
  bool
  shared_ptr<T,I>::is_a () const
  {
    return dynamic_cast<U*> (this->get ());
  }

  /*---------------------------.
  | Intrusive smart pointers.  |
  `---------------------------*/
  template <typename T>
  template <typename U>
  shared_ptr<T, true>::shared_ptr(const shared_ptr<U, true>& other)
    :pointee_(0)
  {
    (*this) = other;
  }
  template <typename T>
  shared_ptr<T, true>::shared_ptr(const shared_ptr<T, true>& other)
    :pointee_(0)
  {
    (*this) = other;
  }
  template <typename T>
  shared_ptr<T, true>::shared_ptr (T* p)
  :pointee_(0)
  {
    (*this) = p;
  }

  template <typename T>
  shared_ptr<T, true>::~shared_ptr()
  {
    // This cast is required, or the compiler uses the shared_ptr ctor,
    // leading to an infinite loop.
    (*this) = (T*)0;
  }

  template <typename T>
  template <typename U>
  shared_ptr<T, true>&
  shared_ptr<T, true>::operator = (const shared_ptr<U, true>& other)
  {
    return (*this) = other.get();
  }

  template <typename T>
  shared_ptr<T, true>&
  shared_ptr<T, true>::operator = (const shared_ptr<T, true>& other)
  {
    return (*this) = other.get();
  }

  template <typename T>
  template <typename U>
  shared_ptr<T, true>&
  shared_ptr<T, true>::operator = (U* other)
  {
    // This is the only place where the counter is used.

    // Decrement current pointee count and delete the object if it reaches 0.
    if (pointee_ && pointee_->counter_dec())
      delete pointee_;

    // Take the pointer, increment counter.
    pointee_ = other;
    if (pointee_)
      pointee_->counter_inc();
    return *this;
  }
  template <typename T> bool
  shared_ptr<T, true>::operator == (const T* p) const
  {
    return pointee_ == p;
  }

  template <typename T> bool
  shared_ptr<T, true>::operator == (const shared_ptr<T, true> &p) const
  {
    return pointee_ == p.get();
  }

  template <typename T> bool
  shared_ptr<T, true>::operator != (const shared_ptr<T, true> &p) const
  {
    return pointee_ != p.get();
  }
  template <typename T> bool
  shared_ptr<T, true>::operator != (const T* p) const
  {
    return pointee_ != p;
  }

  template <typename T>
  template <typename U>
  shared_ptr<U>
  shared_ptr<T, true>::cast() const
  {
    U* ptr = dynamic_cast<U*>(pointee_);
    if (!ptr)
      throw std::bad_cast ();<commit_msg>Fix bug in smart pointers: handle affectation-to-self bug.<commit_after>/**
 ** \file libport/shared-ptr.hxx
 ** \brief Implementation of libport::boost_shared_ptr.
 **/

#ifndef LIBPORT_BOOST_SHARED_PTR_HXX
# define LIBPORT_BOOST_SHARED_PTR_HXX

# include <libport/shared-ptr.hh>

namespace libport
{

  /*-----------------.
  | Ctors and dtor.  |
  `-----------------*/

  template <typename T, bool I>
  template <typename U>
  shared_ptr<T,I>::shared_ptr (const shared_ptr<U,I>& other)
    : super_type (other)
  {
  }

  template <typename T, bool I>
  shared_ptr<T,I>::shared_ptr (const shared_ptr<T,I>& other)
    : super_type (other)
  {
  }

  template <typename T, bool I>
  shared_ptr<T,I>::shared_ptr (T* p)
    : super_type (p)
  {
  }

  template <typename T, bool I>
  shared_ptr<T,I>::~shared_ptr ()
  {
  }


  /*---------------------.
  | Equality operators.  |
  `---------------------*/

  template <typename T, bool I>
  bool
  shared_ptr<T,I>::operator== (const T* other) const
  {
    return this->get () == other;
  }

  template <typename T, bool I>
  bool
  shared_ptr<T,I>::operator!= (const T* other) const
  {
    return !(*this == other);
  }


  /*--------.
  | Casts.  |
  `--------*/

  template <typename T, bool I>
  template <typename U>
  shared_ptr<U>
  shared_ptr<T,I>::unsafe_cast () const
  {
    shared_ptr<U> res;
    (boost::dynamic_pointer_cast<U, element_type> (*this)).swap (res);
    return res;
  }

  template <typename T, bool I>
  template <typename U>
  shared_ptr<U>
  shared_ptr<T,I>::cast () const
  {
    if (!this->get () || !this->is_a<U> ())
      throw std::bad_cast ();
    return unsafe_cast<U> ();
  }

  template <typename T, bool I>
  template <typename U>
  bool
  shared_ptr<T,I>::is_a () const
  {
    return dynamic_cast<U*> (this->get ());
  }

  /*---------------------------.
  | Intrusive smart pointers.  |
  `---------------------------*/
  template <typename T>
  template <typename U>
  shared_ptr<T, true>::shared_ptr(const shared_ptr<U, true>& other)
    :pointee_(0)
  {
    (*this) = other;
  }
  template <typename T>
  shared_ptr<T, true>::shared_ptr(const shared_ptr<T, true>& other)
    :pointee_(0)
  {
    (*this) = other;
  }
  template <typename T>
  shared_ptr<T, true>::shared_ptr (T* p)
  :pointee_(0)
  {
    (*this) = p;
  }

  template <typename T>
  shared_ptr<T, true>::~shared_ptr()
  {
    // This cast is required, or the compiler uses the shared_ptr ctor,
    // leading to an infinite loop.
    (*this) = (T*)0;
  }

  template <typename T>
  template <typename U>
  shared_ptr<T, true>&
  shared_ptr<T, true>::operator = (const shared_ptr<U, true>& other)
  {
    return (*this) = other.get();
  }

  template <typename T>
  shared_ptr<T, true>&
  shared_ptr<T, true>::operator = (const shared_ptr<T, true>& other)
  {
    return (*this) = other.get();
  }

  template <typename T>
  template <typename U>
  shared_ptr<T, true>&
  shared_ptr<T, true>::operator = (U* other)
  {
    // This is the only place where the counter is used.
    if (pointee_ != other)
    {
      // Decrement current pointee count and delete the object if it reaches 0.
      if (pointee_ && pointee_->counter_dec())
        delete pointee_;

      // Take the pointer, increment counter.
      pointee_ = other;
      if (pointee_)
        pointee_->counter_inc();
    }
    return *this;
  }

  template <typename T> bool
  shared_ptr<T, true>::operator == (const T* p) const
  {
    return pointee_ == p;
  }

  template <typename T> bool
  shared_ptr<T, true>::operator == (const shared_ptr<T, true> &p) const
  {
    return pointee_ == p.get();
  }

  template <typename T> bool
  shared_ptr<T, true>::operator != (const shared_ptr<T, true> &p) const
  {
    return pointee_ != p.get();
  }
  template <typename T> bool
  shared_ptr<T, true>::operator != (const T* p) const
  {
    return pointee_ != p;
  }

  template <typename T>
  template <typename U>
  shared_ptr<U>
  shared_ptr<T, true>::cast() const
  {
    U* ptr = dynamic_cast<U*>(pointee_);
    if (!ptr)
      throw std::bad_cast ();
{'fraction_non_alphanumeric': 0.1838909541511772, 'fraction_numerical': 0.0012391573729863693, 'mean_word_length': 2.6736458807464722, 'pattern_counts': {'":': 0, '<': 145, '<?xml version=': 0, '>': 157, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3603154', 'n_tokens_mistral': 2962, 'n_tokens_neox': 2890, 'n_words': 720}