From ce9d2ca31e07679292f0a0378792050756d6ab26 Mon Sep 17 00:00:00 2001
From: Adrian Kummerlaender
Date: Tue, 29 Mar 2016 20:47:27 +0200
Subject: Move `LineAccumulator` into separate compilation unit

---
 src/line_accumulator.cc | 65 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/line_accumulator.h  | 32 ++++++++++++++++++++++++
 src/random.h            |  2 +-
 3 files changed, 98 insertions(+), 1 deletion(-)
 create mode 100644 src/line_accumulator.cc
 create mode 100644 src/line_accumulator.h

(limited to 'src')

diff --git a/src/line_accumulator.cc b/src/line_accumulator.cc
new file mode 100644
index 0000000..cf25c0c
--- /dev/null
+++ b/src/line_accumulator.cc
@@ -0,0 +1,65 @@
+#include "line_accumulator.h"
+
+#include <iostream>
+
+LineAccumulator::LineAccumulator(const std::size_t max_length):
+	max_length_{max_length},
+	random_{},
+	length_{0},
+	tokens_{},
+	spaces_{} { }
+
+LineAccumulator::~LineAccumulator() {
+	this->discharge(false);
+}
+
+void LineAccumulator::operator()(const std::string& word) {
+	if ( ( this->length_ + word.length() + 1 ) > this->max_length_ ) {
+		this->pop_trailing_token();
+		this->discharge(true);
+	}
+
+	this->add_token(word);
+	this->add_space();
+}
+
+void LineAccumulator::add_token(const std::string& token) {
+	this->length_ += token.length();
+	this->tokens_.emplace_back(token);
+}
+
+void LineAccumulator::add_space() {
+	this->add_token(" ");
+	this->spaces_.emplace_back(this->tokens_.size() - 1);
+}
+
+void LineAccumulator::increase_space_at(const std::size_t index) {
+	this->tokens_.at(this->spaces_[index]).append(" ");
+	++this->length_;
+}
+
+void LineAccumulator::pop_trailing_token() {
+	this->length_ -= this->tokens_.back().length();
+	this->tokens_.pop_back();
+	this->spaces_.pop_back();
+}
+
+void LineAccumulator::discharge(const bool full) {
+	if ( full ) {
+		auto range = this->random_.makeRange(0, this->spaces_.size()-1);
+
+		while ( this->length_ < this->max_length_ ) {
+			this->increase_space_at(range.get());
+		}
+	}
+
+	for ( const auto& token : this->tokens_ ) {
+		std::cout << token;
+	}
+
+	std::cout << '\n';
+
+	this->length_ = 0;
+	this->tokens_.clear();
+	this->spaces_.clear();
+}
diff --git a/src/line_accumulator.h b/src/line_accumulator.h
new file mode 100644
index 0000000..ea813a9
--- /dev/null
+++ b/src/line_accumulator.h
@@ -0,0 +1,32 @@
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include "random.h"
+
+class LineAccumulator {
+	public:
+		LineAccumulator(const std::size_t max_length);
+		~LineAccumulator();
+
+		void operator()(const std::string& word);
+
+	private:
+		const std::size_t max_length_;
+
+		utility::Random          random_;
+		std::size_t              length_;
+		std::vector<std::string> tokens_;
+		std::vector<std::size_t> spaces_;
+
+		void add_token(const std::string& token);
+		void add_space();
+
+		void increase_space_at(const std::size_t index);
+		void pop_trailing_token();
+
+		void discharge(const bool full);
+
+};
+
diff --git a/src/random.h b/src/random.h
index 386dc21..73f3215 100644
--- a/src/random.h
+++ b/src/random.h
@@ -22,7 +22,7 @@ class Random {
 
 		Random();
 
-		Range makeRange(const std::size_t, const std::size_t);
+		Range makeRange(const std::size_t a, const std::size_t b);
 
 	private:
 		std::random_device device_;
-- 
cgit v1.2.3