<commit_before>/**
 * \file
 * \brief IntrusiveList template class header
 *
 * \author Copyright (C) 2015 <NAME> http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * \date 2015-12-23
 */

#ifndef ESTD_INTRUSIVELIST_HPP_
#define ESTD_INTRUSIVELIST_HPP_

#include <iterator>

#include <cstddef>

namespace estd
{

namespace internal
{

class IntrusiveListBase;

}

/**
 * \brief IntrusiveListNode class is the node that is needed for the object to be linked in IntrusiveList
 *
 * To some extent, this class can be considered to be a limited (raw) iterator.
 *
 * The object that wants to be linked in IntrusiveList must contain a variable of this type - one for each intrusive
 * list that will be used with object.
 */

class IntrusiveListNode
{
public:

	/// LinkAccessKey class is used to limit access to IntrusiveListNode::link() function - only
	/// internal::IntrusiveListBase can link nodes to the list
	class LinkAccessKey
	{
		friend class internal::IntrusiveListBase;

		/**
		 * \brief LinkAccessKey's constructor
		 */

		constexpr LinkAccessKey()
		{

		}

		LinkAccessKey(const LinkAccessKey&) = delete;
		LinkAccessKey(LinkAccessKey&&) = delete;
		const LinkAccessKey& operator=(const LinkAccessKey&) = delete;
		LinkAccessKey& operator=(LinkAccessKey&&) = delete;
	};

	/**
	 * \brief IntrusiveListNode's constructor
	 */

	constexpr IntrusiveListNode() :
			nextNode_{this},
			previousNode_{this}
	{

	}

	/**
	 * \brief IntrusiveListNode's destructor
	 *
	 * Unlinks the node from the list.
	 */

	~IntrusiveListNode()
	{
		unlink();
	}

	/**
	 * \return reference to next node on the list
	 */

	IntrusiveListNode& getNextNode() const
	{
		return *nextNode_;
	}

	/**
	 * \return reference to previous node on the list
	 */

	IntrusiveListNode& getPreviousNode() const
	{
		return *previousNode_;
	}

	/**
	 * \return true if the node is linked in some list, false otherwise
	 */

	bool isLinked() const
	{
		return nextNode_ != this;
	}

	/**
	 * \brief Links the node in the list before \a position.
	 *
	 * \note Access to this function is restricted only to functions from internal::IntrusiveListBase class
	 *
	 * \param [in] position is a reference to node before which this node will be linked
	 * \param [in] linkAccessKey is used to limit access to this function
	 */

	void link(IntrusiveListNode& position, LinkAccessKey)
	{
		unlink();

		nextNode_ = &position;
		previousNode_ = position.previousNode_;
		position.previousNode_->nextNode_ = this;
		position.previousNode_ = this;
	}

	/**
	 * \brief Swaps contents with another node.
	 *
	 * \param [in] other is a reference to IntrusiveListNode with which contents of this node will be swapped
	 */

	void swap(IntrusiveListNode& other)
	{
		const auto thisWasLinked = isLinked();
		const auto otherWasLinked = other.isLinked();

		if (thisWasLinked == true || otherWasLinked == true)
		{
			using std::swap;
			swap(nextNode_, other.nextNode_);
			swap(previousNode_, other.previousNode_);

			if (thisWasLinked == true)
				other.nextNode_->previousNode_ = other.previousNode_->nextNode_ = &other;
			else
				other.reset();

			if (otherWasLinked == true)
				nextNode_->previousNode_ = previousNode_->nextNode_ = this;
			else
				reset();
		}
	}

	/**
	 * \brief Unlinks the node from the list.
	 */

	void unlink()
	{
		previousNode_->nextNode_ = nextNode_;
		nextNode_->previousNode_ = previousNode_;

		reset();
	}

private:

	/**
	 * \brief Resets the node to the same state as right after construction.
	 */

	void reset()
	{
		nextNode_ = this;
		previousNode_ = this;
	}

	/// reference to next node on the list
	IntrusiveListNode* nextNode_;

	/// reference to previous node on the list
	IntrusiveListNode* previousNode_;
};<commit_msg>IntrusiveListNode: make it move-constructible<commit_after>/**
 * \file
 * \brief IntrusiveList template class header
 *
 * \author Copyright (C) 2015 <NAME> http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * \date 2015-12-23
 */

#ifndef ESTD_INTRUSIVELIST_HPP_
#define ESTD_INTRUSIVELIST_HPP_

#include <iterator>

#include <cstddef>

namespace estd
{

namespace internal
{

class IntrusiveListBase;

}

/**
 * \brief IntrusiveListNode class is the node that is needed for the object to be linked in IntrusiveList
 *
 * To some extent, this class can be considered to be a limited (raw) iterator.
 *
 * The object that wants to be linked in IntrusiveList must contain a variable of this type - one for each intrusive
 * list that will be used with object.
 */

class IntrusiveListNode
{
public:

	/// LinkAccessKey class is used to limit access to IntrusiveListNode::link() function - only
	/// internal::IntrusiveListBase can link nodes to the list
	class LinkAccessKey
	{
		friend class internal::IntrusiveListBase;

		/**
		 * \brief LinkAccessKey's constructor
		 */

		constexpr LinkAccessKey()
		{

		}

		LinkAccessKey(const LinkAccessKey&) = delete;
		LinkAccessKey(LinkAccessKey&&) = delete;
		const LinkAccessKey& operator=(const LinkAccessKey&) = delete;
		LinkAccessKey& operator=(LinkAccessKey&&) = delete;
	};

	/**
	 * \brief IntrusiveListNode's constructor
	 */

	constexpr IntrusiveListNode() :
			nextNode_{this},
			previousNode_{this}
	{

	}

	/**
	 * \brief IntrusiveListNode's move constructor
	 *
	 * \param [in] other is a rvalue reference to IntrusiveListNode used as source of move construction
	 */

	IntrusiveListNode(IntrusiveListNode&& other)
	{
		if (other.isLinked() == false)
		{
			reset();
			return;
		}

		nextNode_ = other.nextNode_;
		previousNode_ = other.previousNode_;
		nextNode_->previousNode_ = previousNode_->nextNode_ = this;
		other.reset();
	}

	/**
	 * \brief IntrusiveListNode's destructor
	 *
	 * Unlinks the node from the list.
	 */

	~IntrusiveListNode()
	{
		unlink();
	}

	/**
	 * \return reference to next node on the list
	 */

	IntrusiveListNode& getNextNode() const
	{
		return *nextNode_;
	}

	/**
	 * \return reference to previous node on the list
	 */

	IntrusiveListNode& getPreviousNode() const
	{
		return *previousNode_;
	}

	/**
	 * \return true if the node is linked in some list, false otherwise
	 */

	bool isLinked() const
	{
		return nextNode_ != this;
	}

	/**
	 * \brief Links the node in the list before \a position.
	 *
	 * \note Access to this function is restricted only to functions from internal::IntrusiveListBase class
	 *
	 * \param [in] position is a reference to node before which this node will be linked
	 * \param [in] linkAccessKey is used to limit access to this function
	 */

	void link(IntrusiveListNode& position, LinkAccessKey)
	{
		unlink();

		nextNode_ = &position;
		previousNode_ = position.previousNode_;
		position.previousNode_->nextNode_ = this;
		position.previousNode_ = this;
	}

	/**
	 * \brief Swaps contents with another node.
	 *
	 * \param [in] other is a reference to IntrusiveListNode with which contents of this node will be swapped
	 */

	void swap(IntrusiveListNode& other)
	{
		const auto thisWasLinked = isLinked();
		const auto otherWasLinked = other.isLinked();

		if (thisWasLinked == true || otherWasLinked == true)
		{
			using std::swap;
			swap(nextNode_, other.nextNode_);
			swap(previousNode_, other.previousNode_);

			if (thisWasLinked == true)
				other.nextNode_->previousNode_ = other.previousNode_->nextNode_ = &other;
			else
				other.reset();

			if (otherWasLinked == true)
				nextNode_->previousNode_ = previousNode_->nextNode_ = this;
			else
				reset();
		}
	}

	/**
	 * \brief Unlinks the node from the list.
	 */

	void unlink()
	{
		previousNode_->nextNode_ = nextNode_;
		nextNode_->previousNode_ = previousNode_;

		reset();
	}

	IntrusiveListNode(const IntrusiveListNode&) = delete;
	const IntrusiveListNode& operator=(const IntrusiveListNode&) = delete;
	IntrusiveListNode& operator=(IntrusiveListNode&&) = delete;

private:

	/**
	 * \brief Resets the node to the same state as right after construction.
	 */

	void reset()
	{
		nextNode_ = this;
		previousNode_ = this;
	}

	/// reference to next node on the list
	IntrusiveListNode* nextNode_;

	/// reference to previous node on the list
	IntrusiveListNode* previousNode_;
};
{'fraction_non_alphanumeric': 0.10210035005834306, 'fraction_numerical': 0.0037339556592765463, 'mean_word_length': 3.534920634920635, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, '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': '1439840', 'n_tokens_mistral': 2949, 'n_tokens_neox': 2585, 'n_words': 856}