<commit_before>/*
 * Copyright 2016, <NAME>
 *
 * This is PUBLIC DOMAIN software so use at your own risk as it comes
 * with no warranties. This code is yours to share, use and modify without
 * any restrictions or obligations.
 *
 * For more information see conwrap/LICENSE or refer refer to http://unlicense.org
 *
 * Author: gimesketvirtadieni at gmail dot com (<NAME>)
 */

#pragma once

#include <queue>
#include <mutex>
#include <exception>
#include <condition_variable>


template<typename T1, typename Container1 = std::deque<T1>>
class ConcurrentQueue
{
	public:
		typedef typename Container1::iterator       iterator;
		typedef typename Container1::const_iterator const_iterator;

		ConcurrentQueue() {}

		virtual ~ConcurrentQueue() {}

		iterator begin()
		{
			return queue_.c.begin();
		}

		const_iterator begin() const
		{
			return queue_.c.begin();
		}

		iterator end()
		{
			return queue_.c.end();
		}

		const_iterator end() const
		{
			return queue_.c.end();
		}

		void push(T1 item)
		{
			{
				std::lock_guard<std::mutex> lock(m_);
				queue_.push(std::move(item));
			}
			data_cond_.notify_one();
		}

bool poll(T1 &popped_item) {
std::lock_guard<std::mutex> lock(m_);
if (queue_.empty()) {
 return false;
}
popped_item = std::move(queue_.front());
queue_.pop();
return true;
}

/// Try to retrieve, if no items, wait till an item is available and try again
void pop(T1 &popped_item) {
std::unique_lock<std::mutex> lock(m_);
while (queue_.empty())
{
data_cond_.wait(lock);
//  This 'while' loop is equal to
//  data_cond_.wait(lock, [](bool result){return !queue_.empty();});
}
popped_item = std::move(queue_.front());
queue_.pop();
}

bool empty() const {
std::lock_guard<std::mutex> lock(m_);
return queue_.empty();
}

unsigned size() const
{
std::lock_guard<std::mutex> lock(m_);
return queue_.size();
}


	protected:

		// defining internal struct to gain access to sequence of elements in a std::queue
		template<typename T2, typename Container2>
		struct IterableQueue : public std::queue<T2, Container2>
		{
			using std::queue<T2, Container2>::c;
		};


	private:
		IterableQueue<T1, Container1> queue_;
		mutable std::mutex m_;
		std::condition_variable data_cond_;

		ConcurrentQueue(const ConcurrentQueue &other) = delete;
		ConcurrentQueue &operator=(const ConcurrentQueue &) = delete;
};<commit_msg>Refactoring<commit_after>/*
 * Copyright 2016, <NAME>
 *
 * This is PUBLIC DOMAIN software so use at your own risk as it comes
 * with no warranties. This code is yours to share, use and modify without
 * any restrictions or obligations.
 *
 * For more information see conwrap/LICENSE or refer refer to http://unlicense.org
 *
 * Author: gimesketvirtadieni at gmail dot com (<NAME>)
 */

#pragma once

#include <condition_variable>
#include <exception>
#include <queue>
#include <mutex>


template<typename T1, typename Container1 = std::deque<T1>>
class ConcurrentQueue
{
	public:
		typedef typename Container1::iterator       iterator;
		typedef typename Container1::const_iterator const_iterator;

		ConcurrentQueue() {}

		virtual ~ConcurrentQueue() {}

		iterator begin()
		{
			return queue_.c.begin();
		}

		const_iterator begin() const
		{
			return queue_.c.begin();
		}

		bool empty() const
		{
			std::lock_guard<std::mutex> lock(m_);
			return queue_.empty();
		}

		iterator end()
		{
			return queue_.c.end();
		}

		const_iterator end() const
		{
			return queue_.c.end();
		}

		void flush()
		{
			{
				std::unique_lock<std::mutex> lock(m_);
				data_cond_.wait(lock, [&] { return queue_.empty();});
			}
		}

		T1* get()
		{
			T1* result = nullptr;
			{
				std::lock_guard<std::mutex> lock(m_);
				if (!queue_.empty()) {
					result = &queue_.front();
				}
			}
			return result;
		}

		void push(T1 item)
		{
			{
				std::lock_guard<std::mutex> lock(m_);
				queue_.push(std::move(item));
			}
			data_cond_.notify_all();
		}

		bool remove() {
			auto result = false;
			{
				std::lock_guard<std::mutex> lock(m_);
				if (!queue_.empty()) {

					// remove the first item in the queue
					queue_.pop();
					data_cond_.notify_all();
					result = true;
				}
			}
			return result;
		}

		unsigned size() const
		{
			std::lock_guard<std::mutex> lock(m_);
			return queue_.size();
		}

		void wait()
		{
			{
				std::unique_lock<std::mutex> lock(m_);
				data_cond_.wait(lock, [&] {return !queue_.empty();});
			}
		}

	protected:
		// defining internal struct to gain access to sequence of elements in a std::queue
		template<typename T2, typename Container2>
		struct IterableQueue : public std::queue<T2, Container2>
		{
			using std::queue<T2, Container2>::c;
		};


	private:
		IterableQueue<T1, Container1> queue_;
		mutable std::mutex m_;
		std::condition_variable data_cond_;

		ConcurrentQueue(const ConcurrentQueue &other) = delete;
		ConcurrentQueue &operator=(const ConcurrentQueue &) = delete;
};
{'fraction_non_alphanumeric': 0.1364195002048341, 'fraction_numerical': 0.00819336337566571, 'mean_word_length': 3.7732160312805476, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 39, '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': '4590726', 'n_tokens_mistral': 1853, 'n_tokens_neox': 1590, 'n_words': 425}