<commit_before>//(c) 2016 by Authors
//This file is a part of ABruijn program.
//Released under the BSD license (see LICENSE file)

#include "multiplicity_inferer.h"
#include "graph_processing.h"
#include "../common/disjoint_set.h"
#include "../common/utils.h"
#include <cmath>

//Estimates the mean coverage and assingns edges multiplicity accordingly
void MultiplicityInferer::estimateCoverage()
{
	const int WINDOW = Config::get("coverage_estimate_window");
	const int SHORT_EDGE = Config::get("unique_edge_length");

	//alternative coverage
	std::unordered_map<GraphEdge*, std::vector<int32_t>> wndCoverage;

	for (auto& edge : _graph.iterEdges())
	{
		size_t numWindows = edge->length() / WINDOW;
		wndCoverage[edge].assign(numWindows, 0);
	}

	for (auto& path : _aligner.getAlignments())
	{
		for (size_t i = 0; i < path.size(); ++i)
		{
			auto& ovlp = path[i].overlap;
			auto& coverage = wndCoverage[path[i].edge];
			for (int pos = ovlp.extBegin / WINDOW + 1;
			 	 pos < ovlp.extEnd / WINDOW; ++pos)
			{
				if (pos >= 0 &&
					pos < (int)coverage.size())
				{
					++coverage[pos];
				}
			}
		}
	}

	int64_t sumCov = 0;
	int64_t sumLength = 0;
	for (auto& edgeCoverage : wndCoverage)
	{
		if (edgeCoverage.first->length() < SHORT_EDGE) continue;
		for (auto& cov : edgeCoverage.second)
		{
			sumCov += (int64_t)cov;
			++sumLength;
		}
	}
	_meanCoverage = (sumLength != 0) ? sumCov / sumLength : 1;

	Logger::get().info() << "Mean edge coverage: " << _meanCoverage;

	std::vector<int32_t> edgesCoverage;
	for (auto edge : _graph.iterEdges())
	{
		if (wndCoverage[edge].empty()) continue;

		GraphEdge* complEdge = _graph.complementEdge(edge);
		int32_t medianCov = (median(wndCoverage[edge]) +
						 	 median(wndCoverage[complEdge])) / 2;

		int estMult = std::round((float)medianCov / _meanCoverage);
		if (estMult == 1)
		{
			edgesCoverage.push_back(medianCov);
		}

		//std::string match = estMult != edge->multiplicity ? "*" : " ";
		std::string covStr;

		Logger::get().debug() << edge->edgeId.signedId() << "\tlen:"
				<< edge->length() << "\tcov:" << medianCov << "\tmult:"
				<< (float)medianCov / _meanCoverage;

		//edge->multiplicity = estMult;
		edge->meanCoverage = medianCov;
	}

	_uniqueCovThreshold = 2;
	if (!edgesCoverage.empty())
	{
		const float MULT = 1.75f;	//at least 1.75x of mean coverage
		_uniqueCovThreshold = MULT * quantile(edgesCoverage, 75);
	}
	Logger::get().debug() << "Unique coverage threshold " << _uniqueCovThreshold;
}

//removes edges with low coverage support from the graph
void MultiplicityInferer::removeUnsupportedEdges()
{
	GraphProcessor proc(_graph, _asmSeqs, _readSeqs);
	auto unbranchingPaths = proc.getUnbranchingPaths();

	int32_t coverageThreshold = this->getMeanCoverage() /
								Config::get("graph_cov_drop_rate");
	Logger::get().debug() << "Read coverage cutoff: " << coverageThreshold;

	std::unordered_set<GraphEdge*> edgesRemove;
	for (auto& path : unbranchingPaths)
	{
		if (!path.id.strand()) continue;

		if (path.meanCoverage <= coverageThreshold)
		{
			Logger::get().debug() << "Low coverage: "
				<< path.edgesStr() << " " << path.meanCoverage;
			for (auto& edge : path.path)
			{
				edgesRemove.insert(edge);
				edgesRemove.insert(_graph.complementEdge(edge));
			}
		}
	}
	for (auto& edge : edgesRemove) _graph.removeEdge(edge);
	Logger::get().debug() << "Removed " << edgesRemove.size() / 2
		<< " unsupported edges";

	_aligner.updateAlignments();
}

void MultiplicityInferer::removeUnsupportedConnections()
{
	std::unordered_map<GraphEdge*, int32_t> rightConnections;
	std::unordered_map<GraphEdge*, int32_t> leftConnections;

	for (auto& readPath : _aligner.getAlignments())
	{
		if (readPath.size() < 2) continue;
		//int overhang = std::max(readPath.front().overlap.curBegin,
		//						readPath.back().overlap.curLen -
		//							readPath.back().overlap.curEnd);
		//if (overhang > (int)Config::get("maximum_overhang")) continue;

		for (size_t i = 0; i < readPath.size() - 1; ++i)
		{
			if (readPath[i].edge == readPath[i + 1].edge &&
				readPath[i].edge->isLooped()) continue;
			if (readPath[i].edge->edgeId ==
				readPath[i + 1].edge->edgeId.rc()) continue;

			++rightConnections[readPath[i].edge];
			++leftConnections[readPath[i + 1].edge];
			GraphEdge* complLeft = _graph.complementEdge(readPath[i].edge);
			GraphEdge* complRight = _graph.complementEdge(readPath[i + 1].edge);
			++rightConnections[complRight];
			++leftConnections[complLeft];
		}
	}

	auto disconnectRight = [this](GraphEdge* edge)
	{
		GraphNode* newNode = _graph.addNode();
		vecRemove(edge->nodeRight->inEdges, edge);
		edge->nodeRight = newNode;
		edge->nodeRight->inEdges.push_back(edge);
	};
	auto disconnectLeft = [this](GraphEdge* edge)
	{
		GraphNode* newNode = _graph.addNode();
		vecRemove(edge->nodeLeft->outEdges, edge);
		edge->nodeLeft = newNode;
		edge->nodeLeft->outEdges.push_back(edge);
	};

	for (auto& edge : _graph.iterEdges())
	{
		if (!edge->edgeId.strand() || edge->isLooped()) continue;
		GraphEdge* complEdge = _graph.complementEdge(edge);

		int32_t coverageThreshold = edge->meanCoverage /
								Config::get("graph_cov_drop_rate");

		//Logger::get().debug() << "Adjacencies: " << edge->edgeId.signedId() << " "
		//	<< leftConnections[edge] / 2 << " " << rightConnections[edge] / 2;

		if (!edge->nodeRight->isEnd() &&
			rightConnections[edge] / 2 < coverageThreshold)
		{
			Logger::get().debug() << "Chimeric right: " <<
				edge->edgeId.signedId() << " " << rightConnections[edge] / 2;

			disconnectRight(edge);
			disconnectLeft(complEdge);

			if (edge->selfComplement) continue;	//already discinnected
		}
		if (!edge->nodeLeft->isEnd() &&
			leftConnections[edge] / 2 < coverageThreshold)
		{
			Logger::get().debug() << "Chimeric left: " <<
				edge->edgeId.signedId() << " " << leftConnections[edge] / 2;

			disconnectLeft(edge);
			disconnectRight(complEdge);
		}
	}

	GraphProcessor proc(_graph, _asmSeqs, _readSeqs);
	proc.trimTips();
	_aligner.updateAlignments();
}

//collapse loops (that also could be viewed as
//bubbles with one branch of length 0)
void MultiplicityInferer::collapseHeterozygousLoops()
{
	const float COV_MULT = 1.5;

	GraphProcessor proc(_graph, _asmSeqs, _readSeqs);
	auto unbranchingPaths = proc.getUnbranchingPaths();

	std::unordered_set<FastaRecord::Id> toUnroll;
	std::unordered_set<FastaRecord::Id> toRemove;
	for (auto& loop : unbranchingPaths)
	{
		if (!loop.isLooped()) continue;

		GraphNode* node = loop.nodeLeft();
		if (node->inEdges.size() != 2 ||
			node->outEdges.size() != 2) continue;

		UnbranchingPath* entrancePath = nullptr;
		UnbranchingPath* exitPath = nullptr;
		for (auto& cand : unbranchingPaths)
		{
			if (cand.nodeRight() == node &&
				loop.id != cand.id) entrancePath = &cand;
			if (cand.nodeLeft() == node &&
				loop.id != cand.id) exitPath = &cand;
		}

		if (entrancePath->isLooped()) continue;
		if (entrancePath->id == exitPath->id.rc()) continue;

		//loop coverage should be roughly equal or less
		if (loop.meanCoverage > COV_MULT * entrancePath->meanCoverage ||
			loop.meanCoverage > COV_MULT * entrancePath->meanCoverage) continue;

		//loop should not be longer than other branches
		if (loop.length > entrancePath->length ||
			loop.length > exitPath->length) continue;

		if (loop.meanCoverage <
			(entrancePath->meanCoverage + exitPath->meanCoverage) / 4)
		{
			toRemove.insert(loop.id);
		}
		else
		{
			toUnroll.insert(loop.id.rc());
		}
	}

	for (auto& path : unbranchingPaths)
	{
		if (toUnroll.count(path.id))
		{
			GraphNode* newNode = _graph.addNode();
			size_t id = path.nodeLeft()->inEdges[0] == path.path.front();
			GraphEdge* prevEdge = path.nodeLeft()->inEdges[id];

			vecRemove(path.nodeLeft()->outEdges, path.path.front());
			vecRemove(path.nodeLeft()->inEdges, prevEdge);
			path.nodeLeft() = newNode;
			newNode->outEdges.push_back(path.path.front());
			prevEdge->nodeRight = newNode;
			newNode->inEdges.push_back(prevEdge);
		}
		if (toRemove.count(path.id))
		{
			GraphNode* newLeft = _graph.addNode();
			GraphNode* newRight = _graph.addNode();

			vecRemove(path.nodeLeft()->outEdges, path.path.front());
			vecRemove(path.nodeLeft()->inEdges, path.path.back());
			path.nodeLeft() = newLeft;
			newRight->inEdges.push_back(path.path.back());
			path.nodeRight() = newRight;
			newLeft->outEdges.push_back(path.path.front());
		}
	}

	Logger::get().debug() << "Unrolled " << toUnroll.size() / 2
		<< " heterozygous loops";
	Logger::get().debug() << "Removed " << toRemove.size() / 2
		<< " heterozygous loops";
	_aligner.updateAlignments();
}

void MultiplicityInferer::collapseHeterozygousBulges()
{
	const float MAX_COV_VAR = 0.20;
	const float MAX_LEN_VAR = 0.50;

	GraphProcessor proc(_graph, _asmSeqs, _readSeqs);
	auto unbranchingPaths = proc.getUnbranchingPaths();

	std::unordered_set<FastaRecord::Id> toSeparate;
	for (auto& path : unbranchingPaths)
	{
		if (path.isLooped()) continue;

		std::vector<UnbranchingPath*> twoPaths;
		for (auto& candEdge : unbranchingPaths)
		{
			if (candEdge.nodeLeft() == path.nodeLeft() &&
				candEdge.nodeRight() == path.nodeRight())
			{
				twoPaths.push_back(&candEdge);
			}
		}

		//making sure the structure is ok
		if (twoPaths.size() != 2) continue;
		if (twoPaths[0]->id == twoPaths[1]->id.rc()) continue;
		if (toSeparate.count(twoPaths[0]->id) ||
			toSeparate.count(twoPaths[1]->id)) continue;
		if (twoPaths[0]->nodeLeft()->inEdges.size() != 1 ||
			twoPaths[0]->nodeRight()->outEdges.size() != 1) continue;

		UnbranchingPath* entrancePath = nullptr;
		UnbranchingPath* exitPath = nullptr;
		for (auto& cand : unbranchingPaths)
		{
			if (cand.nodeRight() ==
				twoPaths[0]->nodeLeft()) entrancePath = &cand;
			if (cand.nodeLeft() == twoPaths[0]->nodeRight()) exitPath = &cand;
		}

		//coverage requirement: sum over two branches roughly equals to
		//exit and entrance coverage
		float covSum = twoPaths[0]->meanCoverage + twoPaths[1]->meanCoverage;
		float entranceDiff = fabsf(covSum - entrancePath->meanCoverage) / covSum;
		float exitDiff = fabsf(covSum - exitPath->meanCoverage) / covSum;
		if (entranceDiff > MAX_COV_VAR || exitDiff > MAX_COV_VAR) continue;

		//length requirement: branches have roughly the same length
		//and are significantly shorter than entrance/exits
		if (abs(twoPaths[0]->length - twoPaths[1]->length) >
			MAX_LEN_VAR * std::min(twoPaths[0]->length,
					 			   twoPaths[1]->length)) continue;
		float bubbleSize = (twoPaths[0]->length + twoPaths[1]->length) / 2;
		if (bubbleSize > entrancePath->length ||
			bubbleSize > exitPath->length) continue;

		if (twoPaths[0]->meanCoverage < twoPaths[1]->meanCoverage)
		{
			toSeparate.insert(twoPaths[0]->id);
			toSeparate.insert(twoPaths[0]->id.rc());
		}
		else
		{
			toSeparate.insert(twoPaths[1]->id);
			toSeparate.insert(twoPaths[1]->id.rc());
		}
	}

	for (auto& path : unbranchingPaths)
	{
		if (toSeparate.count(path.id))
		{
			GraphNode* newLeft = _graph.addNode();
			GraphNode* newRight = _graph.addNode();
			vecRemove(path.nodeLeft()->outEdges, path.path.front());
			vecRemove(path.nodeRight()->inEdges, path.path.back());
			path.nodeLeft() = newLeft;
			path.nodeRight() = newRight;
			newLeft->outEdges.push_back(path.path.front());
			newRight->inEdges.push_back(path.path.back());
		}
	}

	Logger::get().debug() << "Popped " << toSeparate.size() / 2
		<< " heterozygous bulges";
	_aligner.updateAlignments();
}
<commit_msg>low coverage cutoff at least 1<commit_after>//(c) 2016 by Authors
//This file is a part of ABruijn program.
//Released under the BSD license (see LICENSE file)

#include "multiplicity_inferer.h"
#include "graph_processing.h"
#include "../common/disjoint_set.h"
#include "../common/utils.h"
#include <cmath>

//Estimates the mean coverage and assingns edges multiplicity accordingly
void MultiplicityInferer::estimateCoverage()
{
	const int WINDOW = Config::get("coverage_estimate_window");
	const int SHORT_EDGE = Config::get("unique_edge_length");

	//alternative coverage
	std::unordered_map<GraphEdge*, std::vector<int32_t>> wndCoverage;

	for (auto& edge : _graph.iterEdges())
	{
		size_t numWindows = edge->length() / WINDOW;
		wndCoverage[edge].assign(numWindows, 0);
	}

	for (auto& path : _aligner.getAlignments())
	{
		for (size_t i = 0; i < path.size(); ++i)
		{
			auto& ovlp = path[i].overlap;
			auto& coverage = wndCoverage[path[i].edge];
			for (int pos = ovlp.extBegin / WINDOW + 1;
			 	 pos < ovlp.extEnd / WINDOW; ++pos)
			{
				if (pos >= 0 &&
					pos < (int)coverage.size())
				{
					++coverage[pos];
				}
			}
		}
	}

	int64_t sumCov = 0;
	int64_t sumLength = 0;
	for (auto& edgeCoverage : wndCoverage)
	{
		if (edgeCoverage.first->length() < SHORT_EDGE) continue;
		for (auto& cov : edgeCoverage.second)
		{
			sumCov += (int64_t)cov;
			++sumLength;
		}
	}
	_meanCoverage = (sumLength != 0) ? sumCov / sumLength : 1;

	Logger::get().info() << "Mean edge coverage: " << _meanCoverage;

	std::vector<int32_t> edgesCoverage;
	for (auto edge : _graph.iterEdges())
	{
		if (wndCoverage[edge].empty()) continue;

		GraphEdge* complEdge = _graph.complementEdge(edge);
		int32_t medianCov = (median(wndCoverage[edge]) +
						 	 median(wndCoverage[complEdge])) / 2;

		int estMult = std::round((float)medianCov / _meanCoverage);
		if (estMult == 1)
		{
			edgesCoverage.push_back(medianCov);
		}

		//std::string match = estMult != edge->multiplicity ? "*" : " ";
		std::string covStr;

		Logger::get().debug() << edge->edgeId.signedId() << "\tlen:"
				<< edge->length() << "\tcov:" << medianCov << "\tmult:"
				<< (float)medianCov / _meanCoverage;

		//edge->multiplicity = estMult;
		edge->meanCoverage = medianCov;
	}

	_uniqueCovThreshold = 2;
	if (!edgesCoverage.empty())
	{
		const float MULT = 1.75f;	//at least 1.75x of mean coverage
		_uniqueCovThreshold = MULT * quantile(edgesCoverage, 75);
	}
	Logger::get().debug() << "Unique coverage threshold " << _uniqueCovThreshold;
}

//removes edges with low coverage support from the graph
void MultiplicityInferer::removeUnsupportedEdges()
{
	GraphProcessor proc(_graph, _asmSeqs, _readSeqs);
	auto unbranchingPaths = proc.getUnbranchingPaths();

	int32_t coverageThreshold = std::round((float)this->getMeanCoverage() /
											Config::get("graph_cov_drop_rate"));
	coverageThreshold = std::max(1, coverageThreshold);
	Logger::get().debug() << "Read coverage cutoff: " << coverageThreshold;

	std::unordered_set<GraphEdge*> edgesRemove;
	for (auto& path : unbranchingPaths)
	{
		if (!path.id.strand()) continue;

		if (path.meanCoverage <= coverageThreshold)
		{
			Logger::get().debug() << "Low coverage: "
				<< path.edgesStr() << " " << path.meanCoverage;
			for (auto& edge : path.path)
			{
				edgesRemove.insert(edge);
				edgesRemove.insert(_graph.complementEdge(edge));
			}
		}
	}
	for (auto& edge : edgesRemove) _graph.removeEdge(edge);
	Logger::get().debug() << "Removed " << edgesRemove.size() / 2
		<< " unsupported edges";

	_aligner.updateAlignments();
}

void MultiplicityInferer::removeUnsupportedConnections()
{
	std::unordered_map<GraphEdge*, int32_t> rightConnections;
	std::unordered_map<GraphEdge*, int32_t> leftConnections;

	for (auto& readPath : _aligner.getAlignments())
	{
		if (readPath.size() < 2) continue;
		//int overhang = std::max(readPath.front().overlap.curBegin,
		//						readPath.back().overlap.curLen -
		//							readPath.back().overlap.curEnd);
		//if (overhang > (int)Config::get("maximum_overhang")) continue;

		for (size_t i = 0; i < readPath.size() - 1; ++i)
		{
			if (readPath[i].edge == readPath[i + 1].edge &&
				readPath[i].edge->isLooped()) continue;
			if (readPath[i].edge->edgeId ==
				readPath[i + 1].edge->edgeId.rc()) continue;

			++rightConnections[readPath[i].edge];
			++leftConnections[readPath[i + 1].edge];
			GraphEdge* complLeft = _graph.complementEdge(readPath[i].edge);
			GraphEdge* complRight = _graph.complementEdge(readPath[i + 1].edge);
			++rightConnections[complRight];
			++leftConnections[complLeft];
		}
	}

	auto disconnectRight = [this](GraphEdge* edge)
	{
		GraphNode* newNode = _graph.addNode();
		vecRemove(edge->nodeRight->inEdges, edge);
		edge->nodeRight = newNode;
		edge->nodeRight->inEdges.push_back(edge);
	};
	auto disconnectLeft = [this](GraphEdge* edge)
	{
		GraphNode* newNode = _graph.addNode();
		vecRemove(edge->nodeLeft->outEdges, edge);
		edge->nodeLeft = newNode;
		edge->nodeLeft->outEdges.push_back(edge);
	};

	for (auto& edge : _graph.iterEdges())
	{
		if (!edge->edgeId.strand() || edge->isLooped()) continue;
		GraphEdge* complEdge = _graph.complementEdge(edge);

		int32_t coverageThreshold = edge->meanCoverage /
								Config::get("graph_cov_drop_rate");

		//Logger::get().debug() << "Adjacencies: " << edge->edgeId.signedId() << " "
		//	<< leftConnections[edge] / 2 << " " << rightConnections[edge] / 2;

		if (!edge->nodeRight->isEnd() &&
			rightConnections[edge] / 2 < coverageThreshold)
		{
			Logger::get().debug() << "Chimeric right: " <<
				edge->edgeId.signedId() << " " << rightConnections[edge] / 2;

			disconnectRight(edge);
			disconnectLeft(complEdge);

			if (edge->selfComplement) continue;	//already discinnected
		}
		if (!edge->nodeLeft->isEnd() &&
			leftConnections[edge] / 2 < coverageThreshold)
		{
			Logger::get().debug() << "Chimeric left: " <<
				edge->edgeId.signedId() << " " << leftConnections[edge] / 2;

			disconnectLeft(edge);
			disconnectRight(complEdge);
		}
	}

	GraphProcessor proc(_graph, _asmSeqs, _readSeqs);
	proc.trimTips();
	_aligner.updateAlignments();
}

//collapse loops (that also could be viewed as
//bubbles with one branch of length 0)
void MultiplicityInferer::collapseHeterozygousLoops()
{
	const float COV_MULT = 1.5;

	GraphProcessor proc(_graph, _asmSeqs, _readSeqs);
	auto unbranchingPaths = proc.getUnbranchingPaths();

	std::unordered_set<FastaRecord::Id> toUnroll;
	std::unordered_set<FastaRecord::Id> toRemove;
	for (auto& loop : unbranchingPaths)
	{
		if (!loop.isLooped()) continue;

		GraphNode* node = loop.nodeLeft();
		if (node->inEdges.size() != 2 ||
			node->outEdges.size() != 2) continue;

		UnbranchingPath* entrancePath = nullptr;
		UnbranchingPath* exitPath = nullptr;
		for (auto& cand : unbranchingPaths)
		{
			if (cand.nodeRight() == node &&
				loop.id != cand.id) entrancePath = &cand;
			if (cand.nodeLeft() == node &&
				loop.id != cand.id) exitPath = &cand;
		}

		if (entrancePath->isLooped()) continue;
		if (entrancePath->id == exitPath->id.rc()) continue;

		//loop coverage should be roughly equal or less
		if (loop.meanCoverage > COV_MULT * entrancePath->meanCoverage ||
			loop.meanCoverage > COV_MULT * entrancePath->meanCoverage) continue;

		//loop should not be longer than other branches
		if (loop.length > entrancePath->length ||
			loop.length > exitPath->length) continue;

		if (loop.meanCoverage <
			(entrancePath->meanCoverage + exitPath->meanCoverage) / 4)
		{
			toRemove.insert(loop.id);
		}
		else
		{
			toUnroll.insert(loop.id.rc());
		}
	}

	for (auto& path : unbranchingPaths)
	{
		if (toUnroll.count(path.id))
		{
			GraphNode* newNode = _graph.addNode();
			size_t id = path.nodeLeft()->inEdges[0] == path.path.front();
			GraphEdge* prevEdge = path.nodeLeft()->inEdges[id];

			vecRemove(path.nodeLeft()->outEdges, path.path.front());
			vecRemove(path.nodeLeft()->inEdges, prevEdge);
			path.nodeLeft() = newNode;
			newNode->outEdges.push_back(path.path.front());
			prevEdge->nodeRight = newNode;
			newNode->inEdges.push_back(prevEdge);
		}
		if (toRemove.count(path.id))
		{
			GraphNode* newLeft = _graph.addNode();
			GraphNode* newRight = _graph.addNode();

			vecRemove(path.nodeLeft()->outEdges, path.path.front());
			vecRemove(path.nodeLeft()->inEdges, path.path.back());
			path.nodeLeft() = newLeft;
			newRight->inEdges.push_back(path.path.back());
			path.nodeRight() = newRight;
			newLeft->outEdges.push_back(path.path.front());
		}
	}

	Logger::get().debug() << "Unrolled " << toUnroll.size() / 2
		<< " heterozygous loops";
	Logger::get().debug() << "Removed " << toRemove.size() / 2
		<< " heterozygous loops";
	_aligner.updateAlignments();
}

void MultiplicityInferer::collapseHeterozygousBulges()
{
	const float MAX_COV_VAR = 0.20;
	const float MAX_LEN_VAR = 0.50;

	GraphProcessor proc(_graph, _asmSeqs, _readSeqs);
	auto unbranchingPaths = proc.getUnbranchingPaths();

	std::unordered_set<FastaRecord::Id> toSeparate;
	for (auto& path : unbranchingPaths)
	{
		if (path.isLooped()) continue;

		std::vector<UnbranchingPath*> twoPaths;
		for (auto& candEdge : unbranchingPaths)
		{
			if (candEdge.nodeLeft() == path.nodeLeft() &&
				candEdge.nodeRight() == path.nodeRight())
			{
				twoPaths.push_back(&candEdge);
			}
		}

		//making sure the structure is ok
		if (twoPaths.size() != 2) continue;
		if (twoPaths[0]->id == twoPaths[1]->id.rc()) continue;
		if (toSeparate.count(twoPaths[0]->id) ||
			toSeparate.count(twoPaths[1]->id)) continue;
		if (twoPaths[0]->nodeLeft()->inEdges.size() != 1 ||
			twoPaths[0]->nodeRight()->outEdges.size() != 1) continue;

		UnbranchingPath* entrancePath = nullptr;
		UnbranchingPath* exitPath = nullptr;
		for (auto& cand : unbranchingPaths)
		{
			if (cand.nodeRight() ==
				twoPaths[0]->nodeLeft()) entrancePath = &cand;
			if (cand.nodeLeft() == twoPaths[0]->nodeRight()) exitPath = &cand;
		}

		//coverage requirement: sum over two branches roughly equals to
		//exit and entrance coverage
		float covSum = twoPaths[0]->meanCoverage + twoPaths[1]->meanCoverage;
		float entranceDiff = fabsf(covSum - entrancePath->meanCoverage) / covSum;
		float exitDiff = fabsf(covSum - exitPath->meanCoverage) / covSum;
		if (entranceDiff > MAX_COV_VAR || exitDiff > MAX_COV_VAR) continue;

		//length requirement: branches have roughly the same length
		//and are significantly shorter than entrance/exits
		if (abs(twoPaths[0]->length - twoPaths[1]->length) >
			MAX_LEN_VAR * std::min(twoPaths[0]->length,
					 			   twoPaths[1]->length)) continue;
		float bubbleSize = (twoPaths[0]->length + twoPaths[1]->length) / 2;
		if (bubbleSize > entrancePath->length ||
			bubbleSize > exitPath->length) continue;

		if (twoPaths[0]->meanCoverage < twoPaths[1]->meanCoverage)
		{
			toSeparate.insert(twoPaths[0]->id);
			toSeparate.insert(twoPaths[0]->id.rc());
		}
		else
		{
			toSeparate.insert(twoPaths[1]->id);
			toSeparate.insert(twoPaths[1]->id.rc());
		}
	}

	for (auto& path : unbranchingPaths)
	{
		if (toSeparate.count(path.id))
		{
			GraphNode* newLeft = _graph.addNode();
			GraphNode* newRight = _graph.addNode();
			vecRemove(path.nodeLeft()->outEdges, path.path.front());
			vecRemove(path.nodeRight()->inEdges, path.path.back());
			path.nodeLeft() = newLeft;
			path.nodeRight() = newRight;
			newLeft->outEdges.push_back(path.path.front());
			newRight->inEdges.push_back(path.path.back());
		}
	}

	Logger::get().debug() << "Popped " << toSeparate.size() / 2
		<< " heterozygous bulges";
	_aligner.updateAlignments();
}
<|endoftext|>


<commit_before>// bslstl_algorithm.t.cpp                                             -*-C++-*-
#include <bslstl_algorithm.h>

#include <bslma_allocator.h>
#include <bslma_default.h>
#include <bslma_defaultallocatorguard.h>
#include <bslma_destructorguard.h>
#include <bslma_testallocator.h>
#include <bslma_testallocatormonitor.h>
#include <bslma_usesbslmaallocator.h>

#include <bsls_asserttest.h>
#include <bsls_bsltestutil.h>

#include <bsltf_testvaluesarray.h>

#include <functional>
#include <limits.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>      // atoi
#include <string.h>      // strlen

// ============================================================================
//                             TEST PLAN
// ----------------------------------------------------------------------------
// The component under test provides implementations for algorithms not
// provided by the underlying standard library implementation.
// ----------------------------------------------------------------------------
//
// [ 1] bool all_of (InputIter first, InputIter last, PREDICATE pred);
// [ 1] bool any_of (InputIter first, InputIter last, PREDICATE pred);
// [ 1] bool none_of(InputIter first, InputIter last, PREDICATE pred);
// ----------------------------------------------------------------------------

// ============================================================================
//                      STANDARD BDE ASSERT TEST MACROS
// ----------------------------------------------------------------------------
// NOTE: THIS IS A LOW-LEVEL COMPONENT AND MAY NOT USE ANY C++ LIBRARY
// FUNCTIONS, INCLUDING IOSTREAMS.

namespace {

int testStatus = 0;

void aSsErT(bool b, const char *s, int i)
{
    if (b) {
        printf("Error " __FILE__ "(%d): %s    (failed)\n", i, s);
        if (testStatus >= 0 && testStatus <= 100) ++testStatus;
    }
}

}  // close unnamed namespace

// ============================================================================
//                      STANDARD BDE ASSERT TEST MACROS
// ----------------------------------------------------------------------------

#define ASSERT       BSLS_BSLTESTUTIL_ASSERT
#define LOOP_ASSERT  BSLS_BSLTESTUTIL_LOOP_ASSERT
#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT
#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT
#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT
#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT
#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT
#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT
#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT
#define ASSERTV      BSLS_BSLTESTUTIL_ASSERTV

#define Q   BSLS_BSLTESTUTIL_Q   // Quote identifier literally.
#define P   BSLS_BSLTESTUTIL_P   // Print identifier and value.
#define P_  BSLS_BSLTESTUTIL_P_  // P(X) without '\n'.
#define T_  BSLS_BSLTESTUTIL_T_  // Print a tab (w/o newline).
#define L_  BSLS_BSLTESTUTIL_L_  // current Line number

#define RUN_EACH_TYPE BSLTF_TEMPLATETESTFACILITY_RUN_EACH_TYPE

// ============================================================================
//                  NEGATIVE-TEST MACRO ABBREVIATIONS
// ----------------------------------------------------------------------------

#define ASSERT_SAFE_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_PASS(EXPR)
#define ASSERT_SAFE_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_FAIL(EXPR)
#define ASSERT_PASS(EXPR)      BSLS_ASSERTTEST_ASSERT_PASS(EXPR)
#define ASSERT_FAIL(EXPR)      BSLS_ASSERTTEST_ASSERT_FAIL(EXPR)
#define ASSERT_OPT_PASS(EXPR)  BSLS_ASSERTTEST_ASSERT_OPT_PASS(EXPR)
#define ASSERT_OPT_FAIL(EXPR)  BSLS_ASSERTTEST_ASSERT_OPT_FAIL(EXPR)

// ============================================================================
//                  PRINTF FORMAT MACRO ABBREVIATIONS
// ----------------------------------------------------------------------------

#define ZU BSLS_BSLTESTUTIL_FORMAT_ZU

// ============================================================================
//                       GLOBAL TEST ALIASES
// ----------------------------------------------------------------------------

using namespace BloombergLP;

// ============================================================================
//                       GLOBAL TEST VALUES
// ----------------------------------------------------------------------------

static bool             verbose;
static bool         veryVerbose;
static bool     veryVeryVerbose;
static bool veryVeryVeryVerbose;

// ============================================================================
//                              TEST FUNCTIONS
// ----------------------------------------------------------------------------

#ifndef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY

struct IsOdd {
    // A standard compliant C++03 unary predicate functor that returns 'true'
    // if an 'int' value is odd.

    // PUBLIC TYPES
    typedef char  argument_type;
    typedef bool result_type;

    // ACCESSORS
    result_type operator()(argument_type value) const
        // Return 'true' if the specified 'value' is odd, and 'false'
        // otherwise.
    {
        return (value % 2) != 0;
    }
};

// A function (as opposed to a functor)
bool isEven(char value)
    // Return 'true' if the specified 'value' is even, and 'false' otherwise.
{
    return (value % 2) == 0;
}

template <class VALUE>
void runTestAllOf()
    // Test driver for 'all_of'.
{
    struct {
        const char *d_spec;
        bool        d_result;
    } DATA_EVEN[] = {
        { "",    true  },
        { "0",   true  },
        { "1",   false },
        { "00",  true  },
        { "01",  false },
        { "10",  false },
        { "11",  false },
        { "000", true  },
        { "001", false },
        { "010", false },
        { "100", false },
        { "111", false }
    };
    const size_t NUM_DATA_EVEN = sizeof DATA_EVEN / sizeof *DATA_EVEN;

    for (size_t i = 0; i < NUM_DATA_EVEN; ++i) {
        const char *const SPEC = DATA_EVEN[i].d_spec;
        const VALUE       EXP  =
            bsltf::TemplateTestFacility::create<VALUE>(DATA_EVEN[i].d_result);

            bsltf::TestValuesArray<VALUE> values(SPEC);
            ASSERT((EXP == bsl::all_of(values.begin(), values.end(), isEven)));
    }

    struct {
        const char *d_spec;
        bool        d_result;
    } DATA_ODD[] = {
        { "",    true  },
        { "0",   false },
        { "1",   true  },
        { "00",  false },
        { "01",  false },
        { "10",  false },
        { "11",  true  },
        { "000", false },
        { "001", false },
        { "010", false },
        { "100", false },
        { "111", true  }
    };
    const size_t NUM_DATA_ODD = sizeof DATA_ODD / sizeof *DATA_ODD;

    for (size_t i = 0; i < NUM_DATA_ODD; ++i) {
        const char *const SPEC = DATA_ODD[i].d_spec;
        const VALUE       EXP  =
            bsltf::TemplateTestFacility::create<VALUE>(DATA_ODD[i].d_result);

            bsltf::TestValuesArray<VALUE> values(SPEC);
            ASSERT((EXP ==
                          bsl::all_of(values.begin(), values.end(), IsOdd())));
    }
}

template <class VALUE>
void runTestAnyOf()
    // Test driver for 'any_of'.
{
    struct {
        const char *d_spec;
        bool        d_result;
    } DATA_EVEN[] = {
        { "",    false },
        { "0",   true  },
        { "1",   false },
        { "00",  true  },
        { "01",  true  },
        { "10",  true  },
        { "11",  false },
        { "000", true  },
        { "001", true  },
        { "010", true  },
        { "100", true  },
        { "111", false }
    };
    const size_t NUM_DATA_EVEN = sizeof DATA_EVEN / sizeof *DATA_EVEN;

    for (size_t i = 0; i < NUM_DATA_EVEN; ++i) {
        const char *const SPEC = DATA_EVEN[i].d_spec;
        const VALUE       EXP  =
            bsltf::TemplateTestFacility::create<VALUE>(DATA_EVEN[i].d_result);

            bsltf::TestValuesArray<VALUE> values(SPEC);
            ASSERT((EXP == bsl::any_of(values.begin(), values.end(), isEven)));
    }

    struct {
        const char *d_spec;
        bool        d_result;
    } DATA_ODD[] = {
        { "",    false },
        { "0",   false },
        { "1",   true  },
        { "00",  false },
        { "01",  true  },
        { "10",  true  },
        { "11",  true  },
        { "000", false },
        { "001", true  },
        { "010", true  },
        { "100", true  },
        { "111", true  }
    };
    const size_t NUM_DATA_ODD = sizeof DATA_ODD / sizeof *DATA_ODD;

    for (size_t i = 0; i < NUM_DATA_ODD; ++i) {
        const char *const SPEC = DATA_ODD[i].d_spec;
        const VALUE       EXP  =
            bsltf::TemplateTestFacility::create<VALUE>(DATA_ODD[i].d_result);

            bsltf::TestValuesArray<VALUE> values(SPEC);
            ASSERT((EXP ==
                          bsl::any_of(values.begin(), values.end(), IsOdd())));
    }
}

template <class VALUE>
void runTestNoneOf()
    // Test driver for 'none_of'.
{
    struct {
        const char *d_spec;
        bool        d_result;
    } DATA_EVEN[] = {
        { "",    true  },
        { "0",   false },
        { "1",   true  },
        { "00",  false },
        { "01",  false },
        { "10",  false },
        { "11",  true  },
        { "000", false },
        { "001", false },
        { "010", false },
        { "100", false },
        { "111", true  }
    };
    const size_t NUM_DATA_EVEN = sizeof DATA_EVEN / sizeof *DATA_EVEN;

    for (size_t i = 0; i < NUM_DATA_EVEN; ++i) {
        const char *const SPEC = DATA_EVEN[i].d_spec;
        const VALUE       EXP  =
            bsltf::TemplateTestFacility::create<VALUE>(DATA_EVEN[i].d_result);

            bsltf::TestValuesArray<VALUE> values(SPEC);
            ASSERT((EXP ==
                          bsl::none_of(values.begin(), values.end(), isEven)));
    }

    struct {
        const char *d_spec;
        bool        d_result;
    } DATA_ODD[] = {
        { "",    true  },
        { "0",   true  },
        { "1",   false },
        { "00",  true  },
        { "01",  false },
        { "10",  false },
        { "11",  false },
        { "000", true  },
        { "001", false },
        { "010", false },
        { "100", false },
        { "111", false }
    };
    const size_t NUM_DATA_ODD = sizeof DATA_ODD / sizeof *DATA_ODD;

    for (size_t i = 0; i < NUM_DATA_ODD; ++i) {
        const char *const SPEC = DATA_ODD[i].d_spec;
        const VALUE       EXP  =
            bsltf::TemplateTestFacility::create<VALUE>(DATA_ODD[i].d_result);

            bsltf::TestValuesArray<VALUE> values(SPEC);
            ASSERT((EXP ==
                         bsl::none_of(values.begin(), values.end(), IsOdd())));
    }
}

#endif

// ============================================================================
//                            MAIN PROGRAM
// ----------------------------------------------------------------------------

int main(int argc, char *argv[])
{
    int test = argc > 1 ? atoi(argv[1]) : 0;

                verbose = argc > 2;
            veryVerbose = argc > 3;
        veryVeryVerbose = argc > 4;
    veryVeryVeryVerbose = argc > 5;

    printf("TEST " __FILE__ " CASE %d\n", test);

    switch (test) { case 0:
      case 1: {
        // --------------------------------------------------------------------
        // FUNCTIONALITY TEST
        //
        // Concerns:
        //: 1 That the routines exist in the 'bsl' namespace and behave as
        //    expected.
        //
        // Plan:
        //: 1 Run each method with an empty input range and verify that the
        //:   behavior is as expected.
        //: 2 Run each method with a single-element input range and verify that
        //:   the behavior is as expected.
        //: 3 Run each method with multiple-element input range and verify that
        //:   the behavior is as expected.
        //
        // Testing:
        //   bool all_of (InputIter first, InputIter last, PREDICATE pred);
        //   bool any_of (InputIter first, InputIter last, PREDICATE pred);
        //   bool none_of(InputIter first, InputIter last, PREDICATE pred);
        // --------------------------------------------------------------------

        if (verbose) printf("\nFUNCTIONALITY TEST"
                            "\n==================\n");

#ifndef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
            runTestAllOf<char>();
            runTestAnyOf<char>();
            runTestNoneOf<char>();
#endif

      } break;
      default: {
        fprintf(stderr, "WARNING: CASE `%d' NOT FOUND.\n", test);
        testStatus = -1;
      }
    }

    if (testStatus > 0) {
        fprintf(stderr, "Error, non-zero test status = %d.\n", testStatus);
    }
    return testStatus;
}

// ----------------------------------------------------------------------------
// Copyright 2020 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------

<commit_msg>More feedback from Clay and bde-verify; hopefully we're close now<commit_after>// bslstl_algorithm.t.cpp                                             -*-C++-*-
#include <bslstl_algorithm.h>

#include <bslma_allocator.h>
#include <bslma_default.h>
#include <bslma_defaultallocatorguard.h>
#include <bslma_destructorguard.h>
#include <bslma_testallocator.h>
#include <bslma_testallocatormonitor.h>
#include <bslma_usesbslmaallocator.h>

#include <bsls_asserttest.h>
#include <bsls_bsltestutil.h>

#include <bsltf_testvaluesarray.h>
#include <bsltf_templatetestfacility.h>

#include <functional>
#include <limits.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>      // atoi
#include <string.h>      // strlen

// ============================================================================
//                             TEST PLAN
// ----------------------------------------------------------------------------
// The component under test provides implementations for algorithms not
// provided by the underlying standard library implementation.
// ----------------------------------------------------------------------------
//
// [ 1] bool all_of (InputIter first, InputIter last, PREDICATE pred);
// [ 1] bool any_of (InputIter first, InputIter last, PREDICATE pred);
// [ 1] bool none_of(InputIter first, InputIter last, PREDICATE pred);
// ----------------------------------------------------------------------------

// ============================================================================
//                     STANDARD BDE ASSERT TEST FUNCTION
// ----------------------------------------------------------------------------
// NOTE: THIS IS A LOW-LEVEL COMPONENT AND MAY NOT USE ANY C++ LIBRARY
// FUNCTIONS, INCLUDING IOSTREAMS.

namespace {

int testStatus = 0;

void aSsErT(bool b, const char *s, int i)
{
    if (b) {
        printf("Error " __FILE__ "(%d): %s    (failed)\n", i, s);
        if (testStatus >= 0 && testStatus <= 100) ++testStatus;
    }
}

}  // close unnamed namespace

// ============================================================================
//               STANDARD BDE TEST DRIVER MACRO ABBREVIATIONS
// ----------------------------------------------------------------------------

#define ASSERT       BSLS_BSLTESTUTIL_ASSERT
#define LOOP_ASSERT  BSLS_BSLTESTUTIL_LOOP_ASSERT
#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT
#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT
#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT
#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT
#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT
#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT
#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT
#define ASSERTV      BSLS_BSLTESTUTIL_ASSERTV

#define Q   BSLS_BSLTESTUTIL_Q   // Quote identifier literally.
#define P   BSLS_BSLTESTUTIL_P   // Print identifier and value.
#define P_  BSLS_BSLTESTUTIL_P_  // P(X) without '\n'.
#define T_  BSLS_BSLTESTUTIL_T_  // Print a tab (w/o newline).
#define L_  BSLS_BSLTESTUTIL_L_  // current Line number

#define RUN_EACH_TYPE BSLTF_TEMPLATETESTFACILITY_RUN_EACH_TYPE

// ============================================================================
//                  NEGATIVE-TEST MACRO ABBREVIATIONS
// ----------------------------------------------------------------------------

#define ASSERT_SAFE_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_PASS(EXPR)
#define ASSERT_SAFE_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_FAIL(EXPR)
#define ASSERT_PASS(EXPR)      BSLS_ASSERTTEST_ASSERT_PASS(EXPR)
#define ASSERT_FAIL(EXPR)      BSLS_ASSERTTEST_ASSERT_FAIL(EXPR)
#define ASSERT_OPT_PASS(EXPR)  BSLS_ASSERTTEST_ASSERT_OPT_PASS(EXPR)
#define ASSERT_OPT_FAIL(EXPR)  BSLS_ASSERTTEST_ASSERT_OPT_FAIL(EXPR)

// ============================================================================
//                  PRINTF FORMAT MACRO ABBREVIATIONS
// ----------------------------------------------------------------------------

#define ZU BSLS_BSLTESTUTIL_FORMAT_ZU

// ============================================================================
//                       GLOBAL TEST ALIASES
// ----------------------------------------------------------------------------

using namespace BloombergLP;

// ============================================================================
//                       GLOBAL TEST VALUES
// ----------------------------------------------------------------------------

static bool             verbose;
static bool         veryVerbose;
static bool     veryVeryVerbose;
static bool veryVeryVeryVerbose;

// ============================================================================
//                              TEST FUNCTIONS
// ----------------------------------------------------------------------------

#ifndef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY

struct IsOdd {
    // A standard compliant C++03 unary predicate functor that returns 'true'
    // if an 'int' value is odd.

    // PUBLIC TYPES
    typedef char argument_type;
    typedef bool result_type;

    // ACCESSORS
    result_type operator()(argument_type value) const
        // Return 'true' if the specified 'value' is odd, and 'false'
        // otherwise.
    {
        return (value % 2) != 0;
    }
};

// A function (as opposed to a functor)
bool isEven(char value)
    // Return 'true' if the specified 'value' is even, and 'false' otherwise.
{
    return (value % 2) == 0;
}

template <class VALUE>
void runTestAllOf()
    // Test driver for 'all_of'.
{
    const struct {
        const char *d_spec_p;
        bool        d_result;
    } DATA_EVEN[] = {
        { "",    true  },
        { "0",   true  },
        { "1",   false },
        { "00",  true  },
        { "01",  false },
        { "10",  false },
        { "11",  false },
        { "000", true  },
        { "001", false },
        { "010", false },
        { "100", false },
        { "101", false },
        { "111", false }
    };
    const size_t NUM_DATA_EVEN = sizeof DATA_EVEN / sizeof *DATA_EVEN;

    for (size_t i = 0; i < NUM_DATA_EVEN; ++i) {
        const char *const SPEC = DATA_EVEN[i].d_spec_p;
        const VALUE       EXP  =
            bsltf::TemplateTestFacility::create<VALUE>(DATA_EVEN[i].d_result);

            bsltf::TestValuesArray<VALUE> values(SPEC);
            ASSERT((EXP == bsl::all_of(values.begin(), values.end(), isEven)));
    }

    const struct {
        const char *d_spec_p;
        bool        d_result;
    } DATA_ODD[] = {
        { "",    true  },
        { "0",   false },
        { "1",   true  },
        { "00",  false },
        { "01",  false },
        { "10",  false },
        { "11",  true  },
        { "000", false },
        { "001", false },
        { "010", false },
        { "100", false },
        { "101", false },
        { "111", true  }
    };
    const size_t NUM_DATA_ODD = sizeof DATA_ODD / sizeof *DATA_ODD;

    for (size_t i = 0; i < NUM_DATA_ODD; ++i) {
        const char *const SPEC = DATA_ODD[i].d_spec_p;
        const VALUE       EXP  =
            bsltf::TemplateTestFacility::create<VALUE>(DATA_ODD[i].d_result);

            bsltf::TestValuesArray<VALUE> values(SPEC);
            ASSERT((EXP ==
                          bsl::all_of(values.begin(), values.end(), IsOdd())));
    }
}

template <class VALUE>
void runTestAnyOf()
    // Test driver for 'any_of'.
{
    const struct {
        const char *d_spec_p;
        bool        d_result;
    } DATA_EVEN[] = {
        { "",    false },
        { "0",   true  },
        { "1",   false },
        { "00",  true  },
        { "01",  true  },
        { "10",  true  },
        { "11",  false },
        { "000", true  },
        { "001", true  },
        { "010", true  },
        { "100", true  },
        { "101", true  },
        { "111", false }
    };
    const size_t NUM_DATA_EVEN = sizeof DATA_EVEN / sizeof *DATA_EVEN;

    for (size_t i = 0; i < NUM_DATA_EVEN; ++i) {
        const char *const SPEC = DATA_EVEN[i].d_spec_p;
        const VALUE       EXP  =
            bsltf::TemplateTestFacility::create<VALUE>(DATA_EVEN[i].d_result);

            bsltf::TestValuesArray<VALUE> values(SPEC);
            ASSERT((EXP == bsl::any_of(values.begin(), values.end(), isEven)));
    }

    const struct {
        const char *d_spec_p;
        bool        d_result;
    } DATA_ODD[] = {
        { "",    false },
        { "0",   false },
        { "1",   true  },
        { "00",  false },
        { "01",  true  },
        { "10",  true  },
        { "11",  true  },
        { "000", false },
        { "001", true  },
        { "010", true  },
        { "100", true  },
        { "101", true  },
        { "111", true  }
    };
    const size_t NUM_DATA_ODD = sizeof DATA_ODD / sizeof *DATA_ODD;

    for (size_t i = 0; i < NUM_DATA_ODD; ++i) {
        const char *const SPEC = DATA_ODD[i].d_spec_p;
        const VALUE       EXP  =
            bsltf::TemplateTestFacility::create<VALUE>(DATA_ODD[i].d_result);

            bsltf::TestValuesArray<VALUE> values(SPEC);
            ASSERT((EXP ==
                          bsl::any_of(values.begin(), values.end(), IsOdd())));
    }
}

template <class VALUE>
void runTestNoneOf()
    // Test driver for 'none_of'.
{
    const struct {
        const char *d_spec_p;
        bool        d_result;
    } DATA_EVEN[] = {
        { "",    true  },
        { "0",   false },
        { "1",   true  },
        { "00",  false },
        { "01",  false },
        { "10",  false },
        { "11",  true  },
        { "000", false },
        { "001", false },
        { "010", false },
        { "100", false },
        { "101", false },
        { "111", true  }
    };
    const size_t NUM_DATA_EVEN = sizeof DATA_EVEN / sizeof *DATA_EVEN;

    for (size_t i = 0; i < NUM_DATA_EVEN; ++i) {
        const char *const SPEC = DATA_EVEN[i].d_spec_p;
        const VALUE       EXP  =
            bsltf::TemplateTestFacility::create<VALUE>(DATA_EVEN[i].d_result);

            bsltf::TestValuesArray<VALUE> values(SPEC);
            ASSERT((EXP ==
                          bsl::none_of(values.begin(), values.end(), isEven)));
    }

    const struct {
        const char *d_spec_p;
        bool        d_result;
    } DATA_ODD[] = {
        { "",    true  },
        { "0",   true  },
        { "1",   false },
        { "00",  true  },
        { "01",  false },
        { "10",  false },
        { "11",  false },
        { "000", true  },
        { "001", false },
        { "010", false },
        { "100", false },
        { "101", false },
        { "111", false }
    };
    const size_t NUM_DATA_ODD = sizeof DATA_ODD / sizeof *DATA_ODD;

    for (size_t i = 0; i < NUM_DATA_ODD; ++i) {
        const char *const SPEC = DATA_ODD[i].d_spec_p;
        const VALUE       EXP  =
            bsltf::TemplateTestFacility::create<VALUE>(DATA_ODD[i].d_result);

            bsltf::TestValuesArray<VALUE> values(SPEC);
            ASSERT((EXP ==
                         bsl::none_of(values.begin(), values.end(), IsOdd())));
    }
}

#endif

// ============================================================================
//                            MAIN PROGRAM
// ----------------------------------------------------------------------------

int main(int argc, char *argv[])
{
    int test = argc > 1 ? atoi(argv[1]) : 0;

                verbose = argc > 2;
            veryVerbose = argc > 3;
        veryVeryVerbose = argc > 4;
    veryVeryVeryVerbose = argc > 5;

    printf("TEST " __FILE__ " CASE %d\n", test);

    switch (test) { case 0:
      case 1: {
        // --------------------------------------------------------------------
        // FUNCTIONALITY TEST
        //
        // Concerns:
        //: 1 That the routines exist in the 'bsl' namespace and behave as
        //    expected.
        //
        // Plan:
        //: 1 Run each method with an empty input range and verify that the
        //:   behavior is as expected.
        //: 2 Run each method with a single-element input range and verify that
        //:   the behavior is as expected.
        //: 3 Run each method with multiple-element input range and verify that
        //:   the behavior is as expected.
        //
        // Testing:
        //   bool all_of (InputIter first, InputIter last, PREDICATE pred);
        //   bool any_of (InputIter first, InputIter last, PREDICATE pred);
        //   bool none_of(InputIter first, InputIter last, PREDICATE pred);
        // --------------------------------------------------------------------

        if (verbose) printf("\nFUNCTIONALITY TEST"
                            "\n==================\n");

#ifndef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
        runTestAllOf<char>();
        runTestAnyOf<char>();
        runTestNoneOf<char>();
#endif

      } break;
      default: {
        fprintf(stderr, "WARNING: CASE `%d' NOT FOUND.\n", test);
        testStatus = -1;
      }
    }

    if (testStatus > 0) {
        fprintf(stderr, "Error, non-zero test status = %d.\n", testStatus);
    }
    return testStatus;
}

// ----------------------------------------------------------------------------
// Copyright 2020 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------
<|endoftext|>


<commit_before>// bslstl_algorithm.t.cpp                                             -*-C++-*-
#include <bslstl_algorithm.h>

#include <bslma_allocator.h>
#include <bslma_default.h>
#include <bslma_defaultallocatorguard.h>
#include <bslma_destructorguard.h>
#include <bslma_testallocator.h>
#include <bslma_testallocatormonitor.h>
#include <bslma_usesbslmaallocator.h>

#include <bsls_asserttest.h>
#include <bsls_bsltestutil.h>

#include <bsltf_testvaluesarray.h>
#include <bsltf_templatetestfacility.h>

#include <functional>
#include <limits.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>      // atoi
#include <string.h>      // strlen

// ============================================================================
//                             TEST PLAN
// ----------------------------------------------------------------------------
// The component under test provides implementations for algorithms not
// provided by the underlying standard library implementation.
// ----------------------------------------------------------------------------
//
// [ 1] bool all_of (InputIter first, InputIter last, PREDICATE pred);
// [ 1] bool any_of (InputIter first, InputIter last, PREDICATE pred);
// [ 1] bool none_of(InputIter first, InputIter last, PREDICATE pred);
// ----------------------------------------------------------------------------

// ============================================================================
//                     STANDARD BDE ASSERT TEST FUNCTION
// ----------------------------------------------------------------------------
// NOTE: THIS IS A LOW-LEVEL COMPONENT AND MAY NOT USE ANY C++ LIBRARY
// FUNCTIONS, INCLUDING IOSTREAMS.

namespace {

int testStatus = 0;

void aSsErT(bool b, const char *s, int i)
{
    if (b) {
        printf("Error " __FILE__ "(%d): %s    (failed)\n", i, s);
        if (testStatus >= 0 && testStatus <= 100) ++testStatus;
    }
}

}  // close unnamed namespace

// ============================================================================
//               STANDARD BDE TEST DRIVER MACRO ABBREVIATIONS
// ----------------------------------------------------------------------------

#define ASSERT       BSLS_BSLTESTUTIL_ASSERT
#define LOOP_ASSERT  BSLS_BSLTESTUTIL_LOOP_ASSERT
#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT
#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT
#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT
#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT
#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT
#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT
#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT
#define ASSERTV      BSLS_BSLTESTUTIL_ASSERTV

#define Q   BSLS_BSLTESTUTIL_Q   // Quote identifier literally.
#define P   BSLS_BSLTESTUTIL_P   // Print identifier and value.
#define P_  BSLS_BSLTESTUTIL_P_  // P(X) without '\n'.
#define T_  BSLS_BSLTESTUTIL_T_  // Print a tab (w/o newline).
#define L_  BSLS_BSLTESTUTIL_L_  // current Line number

#define RUN_EACH_TYPE BSLTF_TEMPLATETESTFACILITY_RUN_EACH_TYPE

// ============================================================================
//                  NEGATIVE-TEST MACRO ABBREVIATIONS
// ----------------------------------------------------------------------------

#define ASSERT_SAFE_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_PASS(EXPR)
#define ASSERT_SAFE_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_FAIL(EXPR)
#define ASSERT_PASS(EXPR)      BSLS_ASSERTTEST_ASSERT_PASS(EXPR)
#define ASSERT_FAIL(EXPR)      BSLS_ASSERTTEST_ASSERT_FAIL(EXPR)
#define ASSERT_OPT_PASS(EXPR)  BSLS_ASSERTTEST_ASSERT_OPT_PASS(EXPR)
#define ASSERT_OPT_FAIL(EXPR)  BSLS_ASSERTTEST_ASSERT_OPT_FAIL(EXPR)

// ============================================================================
//                  PRINTF FORMAT MACRO ABBREVIATIONS
// ----------------------------------------------------------------------------

#define ZU BSLS_BSLTESTUTIL_FORMAT_ZU

// ============================================================================
//                       GLOBAL TEST ALIASES
// ----------------------------------------------------------------------------

using namespace BloombergLP;

// ============================================================================
//                       GLOBAL TEST VALUES
// ----------------------------------------------------------------------------

static bool             verbose;
static bool         veryVerbose;
static bool     veryVeryVerbose;
static bool veryVeryVeryVerbose;

// ============================================================================
//                              TEST FUNCTIONS
// ----------------------------------------------------------------------------

#ifndef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY

struct IsOdd {
    // A standard compliant C++03 unary predicate functor that returns 'true'
    // if an 'int' value is odd.

    // PUBLIC TYPES
    typedef char argument_type;
    typedef bool result_type;

    // ACCESSORS
    result_type operator()(argument_type value) const
        // Return 'true' if the specified 'value' is odd, and 'false'
        // otherwise.
    {
        return (value % 2) != 0;
    }
};

// A function (as opposed to a functor)
bool isEven(char value)
    // Return 'true' if the specified 'value' is even, and 'false' otherwise.
{
    return (value % 2) == 0;
}

template <class VALUE>
void runTestAllOf()
    // Test driver for 'all_of'.
{
    const struct {
        const char *d_spec_p;
        bool        d_result;
    } DATA_EVEN[] = {
        { "",    true  },
        { "0",   true  },
        { "1",   false },
        { "00",  true  },
        { "01",  false },
        { "10",  false },
        { "11",  false },
        { "000", true  },
        { "001", false },
        { "010", false },
        { "100", false },
        { "101", false },
        { "111", false }
    };
    const size_t NUM_DATA_EVEN = sizeof DATA_EVEN / sizeof *DATA_EVEN;

    for (size_t i = 0; i < NUM_DATA_EVEN; ++i) {
        const char *const SPEC = DATA_EVEN[i].d_spec_p;
        const VALUE       EXP  =
            bsltf::TemplateTestFacility::create<VALUE>(DATA_EVEN[i].d_result);

            bsltf::TestValuesArray<VALUE> values(SPEC);
            ASSERT((EXP == bsl::all_of(values.begin(), values.end(), isEven)));
    }

    const struct {
        const char *d_spec_p;
        bool        d_result;
    } DATA_ODD[] = {
        { "",    true  },
        { "0",   false },
        { "1",   true  },
        { "00",  false },
        { "01",  false },
        { "10",  false },
        { "11",  true  },
        { "000", false },
        { "001", false },
        { "010", false },
        { "100", false },
        { "101", false },
        { "111", true  }
    };
    const size_t NUM_DATA_ODD = sizeof DATA_ODD / sizeof *DATA_ODD;

    for (size_t i = 0; i < NUM_DATA_ODD; ++i) {
        const char *const SPEC = DATA_ODD[i].d_spec_p;
        const VALUE       EXP  =
            bsltf::TemplateTestFacility::create<VALUE>(DATA_ODD[i].d_result);

            bsltf::TestValuesArray<VALUE> values(SPEC);
            ASSERT((EXP ==
                          bsl::all_of(values.begin(), values.end(), IsOdd())));
    }
}

template <class VALUE>
void runTestAnyOf()
    // Test driver for 'any_of'.
{
    const struct {
        const char *d_spec_p;
        bool        d_result;
    } DATA_EVEN[] = {
        { "",    false },
        { "0",   true  },
        { "1",   false },
        { "00",  true  },
        { "01",  true  },
        { "10",  true  },
        { "11",  false },
        { "000", true  },
        { "001", true  },
        { "010", true  },
        { "100", true  },
        { "101", true  },
        { "111", false }
    };
    const size_t NUM_DATA_EVEN = sizeof DATA_EVEN / sizeof *DATA_EVEN;

    for (size_t i = 0; i < NUM_DATA_EVEN; ++i) {
        const char *const SPEC = DATA_EVEN[i].d_spec_p;
        const VALUE       EXP  =
            bsltf::TemplateTestFacility::create<VALUE>(DATA_EVEN[i].d_result);

            bsltf::TestValuesArray<VALUE> values(SPEC);
            ASSERT((EXP == bsl::any_of(values.begin(), values.end(), isEven)));
    }

    const struct {
        const char *d_spec_p;
        bool        d_result;
    } DATA_ODD[] = {
        { "",    false },
        { "0",   false },
        { "1",   true  },
        { "00",  false },
        { "01",  true  },
        { "10",  true  },
        { "11",  true  },
        { "000", false },
        { "001", true  },
        { "010", true  },
        { "100", true  },
        { "101", true  },
        { "111", true  }
    };
    const size_t NUM_DATA_ODD = sizeof DATA_ODD / sizeof *DATA_ODD;

    for (size_t i = 0; i < NUM_DATA_ODD; ++i) {
        const char *const SPEC = DATA_ODD[i].d_spec_p;
        const VALUE       EXP  =
            bsltf::TemplateTestFacility::create<VALUE>(DATA_ODD[i].d_result);

            bsltf::TestValuesArray<VALUE> values(SPEC);
            ASSERT((EXP ==
                          bsl::any_of(values.begin(), values.end(), IsOdd())));
    }
}

template <class VALUE>
void runTestNoneOf()
    // Test driver for 'none_of'.
{
    const struct {
        const char *d_spec_p;
        bool        d_result;
    } DATA_EVEN[] = {
        { "",    true  },
        { "0",   false },
        { "1",   true  },
        { "00",  false },
        { "01",  false },
        { "10",  false },
        { "11",  true  },
        { "000", false },
        { "001", false },
        { "010", false },
        { "100", false },
        { "101", false },
        { "111", true  }
    };
    const size_t NUM_DATA_EVEN = sizeof DATA_EVEN / sizeof *DATA_EVEN;

    for (size_t i = 0; i < NUM_DATA_EVEN; ++i) {
        const char *const SPEC = DATA_EVEN[i].d_spec_p;
        const VALUE       EXP  =
            bsltf::TemplateTestFacility::create<VALUE>(DATA_EVEN[i].d_result);

            bsltf::TestValuesArray<VALUE> values(SPEC);
            ASSERT((EXP ==
                          bsl::none_of(values.begin(), values.end(), isEven)));
    }

    const struct {
        const char *d_spec_p;
        bool        d_result;
    } DATA_ODD[] = {
        { "",    true  },
        { "0",   true  },
        { "1",   false },
        { "00",  true  },
        { "01",  false },
        { "10",  false },
        { "11",  false },
        { "000", true  },
        { "001", false },
        { "010", false },
        { "100", false },
        { "101", false },
        { "111", false }
    };
    const size_t NUM_DATA_ODD = sizeof DATA_ODD / sizeof *DATA_ODD;

    for (size_t i = 0; i < NUM_DATA_ODD; ++i) {
        const char *const SPEC = DATA_ODD[i].d_spec_p;
        const VALUE       EXP  =
            bsltf::TemplateTestFacility::create<VALUE>(DATA_ODD[i].d_result);

            bsltf::TestValuesArray<VALUE> values(SPEC);
            ASSERT((EXP ==
                         bsl::none_of(values.begin(), values.end(), IsOdd())));
    }
}

#endif

// ============================================================================
//                            MAIN PROGRAM
// ----------------------------------------------------------------------------

int main(int argc, char *argv[])
{
    int test = argc > 1 ? atoi(argv[1]) : 0;

                verbose = argc > 2;
            veryVerbose = argc > 3;
        veryVeryVerbose = argc > 4;
    veryVeryVeryVerbose = argc > 5;

    printf("TEST " __FILE__ " CASE %d\n", test);

    switch (test) { case 0:
      case 1: {
        // --------------------------------------------------------------------
        // FUNCTIONALITY TEST
        //
        // Concerns:
        //: 1 That the routines exist in the 'bsl' namespace and behave as
        //    expected.
        //
        // Plan:
        //: 1 Run each method with an empty input range and verify that the
        //:   behavior is as expected.
        //: 2 Run each method with a single-element input range and verify that
        //:   the behavior is as expected.
        //: 3 Run each method with multiple-element input range and verify that
        //:   the behavior is as expected.
        //
        // Testing:
        //   bool all_of (InputIter first, InputIter last, PREDICATE pred);
        //   bool any_of (InputIter first, InputIter last, PREDICATE pred);
        //   bool none_of(InputIter first, InputIter last, PREDICATE pred);
        // --------------------------------------------------------------------

        if (verbose) printf("\nFUNCTIONALITY TEST"
                            "\n==================\n");

#ifndef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
        runTestAllOf<char>();
        runTestAnyOf<char>();
        runTestNoneOf<char>();
#endif

      } break;
      default: {
        fprintf(stderr, "WARNING: CASE `%d' NOT FOUND.\n", test);
        testStatus = -1;
      }
    }

    if (testStatus > 0) {
        fprintf(stderr, "Error, non-zero test status = %d.\n", testStatus);
    }
    return testStatus;
}

// ----------------------------------------------------------------------------
// Copyright 2020 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------
<commit_msg>Alphabetize the includes of the blstf headers<commit_after>// bslstl_algorithm.t.cpp                                             -*-C++-*-
#include <bslstl_algorithm.h>

#include <bslma_allocator.h>
#include <bslma_default.h>
#include <bslma_defaultallocatorguard.h>
#include <bslma_destructorguard.h>
#include <bslma_testallocator.h>
#include <bslma_testallocatormonitor.h>
#include <bslma_usesbslmaallocator.h>

#include <bsls_asserttest.h>
#include <bsls_bsltestutil.h>

#include <bsltf_templatetestfacility.h>
#include <bsltf_testvaluesarray.h>

#include <functional>
#include <limits.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>      // atoi
#include <string.h>      // strlen

// ============================================================================
//                             TEST PLAN
// ----------------------------------------------------------------------------
// The component under test provides implementations for algorithms not
// provided by the underlying standard library implementation.
// ----------------------------------------------------------------------------
//
// [ 1] bool all_of (InputIter first, InputIter last, PREDICATE pred);
// [ 1] bool any_of (InputIter first, InputIter last, PREDICATE pred);
// [ 1] bool none_of(InputIter first, InputIter last, PREDICATE pred);
// ----------------------------------------------------------------------------

// ============================================================================
//                     STANDARD BDE ASSERT TEST FUNCTION
// ----------------------------------------------------------------------------
// NOTE: THIS IS A LOW-LEVEL COMPONENT AND MAY NOT USE ANY C++ LIBRARY
// FUNCTIONS, INCLUDING IOSTREAMS.

namespace {

int testStatus = 0;

void aSsErT(bool b, const char *s, int i)
{
    if (b) {
        printf("Error " __FILE__ "(%d): %s    (failed)\n", i, s);
        if (testStatus >= 0 && testStatus <= 100) ++testStatus;
    }
}

}  // close unnamed namespace

// ============================================================================
//               STANDARD BDE TEST DRIVER MACRO ABBREVIATIONS
// ----------------------------------------------------------------------------

#define ASSERT       BSLS_BSLTESTUTIL_ASSERT
#define LOOP_ASSERT  BSLS_BSLTESTUTIL_LOOP_ASSERT
#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT
#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT
#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT
#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT
#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT
#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT
#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT
#define ASSERTV      BSLS_BSLTESTUTIL_ASSERTV

#define Q   BSLS_BSLTESTUTIL_Q   // Quote identifier literally.
#define P   BSLS_BSLTESTUTIL_P   // Print identifier and value.
#define P_  BSLS_BSLTESTUTIL_P_  // P(X) without '\n'.
#define T_  BSLS_BSLTESTUTIL_T_  // Print a tab (w/o newline).
#define L_  BSLS_BSLTESTUTIL_L_  // current Line number

#define RUN_EACH_TYPE BSLTF_TEMPLATETESTFACILITY_RUN_EACH_TYPE

// ============================================================================
//                  NEGATIVE-TEST MACRO ABBREVIATIONS
// ----------------------------------------------------------------------------

#define ASSERT_SAFE_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_PASS(EXPR)
#define ASSERT_SAFE_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_FAIL(EXPR)
#define ASSERT_PASS(EXPR)      BSLS_ASSERTTEST_ASSERT_PASS(EXPR)
#define ASSERT_FAIL(EXPR)      BSLS_ASSERTTEST_ASSERT_FAIL(EXPR)
#define ASSERT_OPT_PASS(EXPR)  BSLS_ASSERTTEST_ASSERT_OPT_PASS(EXPR)
#define ASSERT_OPT_FAIL(EXPR)  BSLS_ASSERTTEST_ASSERT_OPT_FAIL(EXPR)

// ============================================================================
//                  PRINTF FORMAT MACRO ABBREVIATIONS
// ----------------------------------------------------------------------------

#define ZU BSLS_BSLTESTUTIL_FORMAT_ZU

// ============================================================================
//                       GLOBAL TEST ALIASES
// ----------------------------------------------------------------------------

using namespace BloombergLP;

// ============================================================================
//                       GLOBAL TEST VALUES
// ----------------------------------------------------------------------------

static bool             verbose;
static bool         veryVerbose;
static bool     veryVeryVerbose;
static bool veryVeryVeryVerbose;

// ============================================================================
//                              TEST FUNCTIONS
// ----------------------------------------------------------------------------

#ifndef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY

struct IsOdd {
    // A standard compliant C++03 unary predicate functor that returns 'true'
    // if an 'int' value is odd.

    // PUBLIC TYPES
    typedef char argument_type;
    typedef bool result_type;

    // ACCESSORS
    result_type operator()(argument_type value) const
        // Return 'true' if the specified 'value' is odd, and 'false'
        // otherwise.
    {
        return (value % 2) != 0;
    }
};

// A function (as opposed to a functor)
bool isEven(char value)
    // Return 'true' if the specified 'value' is even, and 'false' otherwise.
{
    return (value % 2) == 0;
}

template <class VALUE>
void runTestAllOf()
    // Test driver for 'all_of'.
{
    const struct {
        const char *d_spec_p;
        bool        d_result;
    } DATA_EVEN[] = {
        { "",    true  },
        { "0",   true  },
        { "1",   false },
        { "00",  true  },
        { "01",  false },
        { "10",  false },
        { "11",  false },
        { "000", true  },
        { "001", false },
        { "010", false },
        { "100", false },
        { "101", false },
        { "111", false }
    };
    const size_t NUM_DATA_EVEN = sizeof DATA_EVEN / sizeof *DATA_EVEN;

    for (size_t i = 0; i < NUM_DATA_EVEN; ++i) {
        const char *const SPEC = DATA_EVEN[i].d_spec_p;
        const VALUE       EXP  =
            bsltf::TemplateTestFacility::create<VALUE>(DATA_EVEN[i].d_result);

            bsltf::TestValuesArray<VALUE> values(SPEC);
            ASSERT((EXP == bsl::all_of(values.begin(), values.end(), isEven)));
    }

    const struct {
        const char *d_spec_p;
        bool        d_result;
    } DATA_ODD[] = {
        { "",    true  },
        { "0",   false },
        { "1",   true  },
        { "00",  false },
        { "01",  false },
        { "10",  false },
        { "11",  true  },
        { "000", false },
        { "001", false },
        { "010", false },
        { "100", false },
        { "101", false },
        { "111", true  }
    };
    const size_t NUM_DATA_ODD = sizeof DATA_ODD / sizeof *DATA_ODD;

    for (size_t i = 0; i < NUM_DATA_ODD; ++i) {
        const char *const SPEC = DATA_ODD[i].d_spec_p;
        const VALUE       EXP  =
            bsltf::TemplateTestFacility::create<VALUE>(DATA_ODD[i].d_result);

            bsltf::TestValuesArray<VALUE> values(SPEC);
            ASSERT((EXP ==
                          bsl::all_of(values.begin(), values.end(), IsOdd())));
    }
}

template <class VALUE>
void runTestAnyOf()
    // Test driver for 'any_of'.
{
    const struct {
        const char *d_spec_p;
        bool        d_result;
    } DATA_EVEN[] = {
        { "",    false },
        { "0",   true  },
        { "1",   false },
        { "00",  true  },
        { "01",  true  },
        { "10",  true  },
        { "11",  false },
        { "000", true  },
        { "001", true  },
        { "010", true  },
        { "100", true  },
        { "101", true  },
        { "111", false }
    };
    const size_t NUM_DATA_EVEN = sizeof DATA_EVEN / sizeof *DATA_EVEN;

    for (size_t i = 0; i < NUM_DATA_EVEN; ++i) {
        const char *const SPEC = DATA_EVEN[i].d_spec_p;
        const VALUE       EXP  =
            bsltf::TemplateTestFacility::create<VALUE>(DATA_EVEN[i].d_result);

            bsltf::TestValuesArray<VALUE> values(SPEC);
            ASSERT((EXP == bsl::any_of(values.begin(), values.end(), isEven)));
    }

    const struct {
        const char *d_spec_p;
        bool        d_result;
    } DATA_ODD[] = {
        { "",    false },
        { "0",   false },
        { "1",   true  },
        { "00",  false },
        { "01",  true  },
        { "10",  true  },
        { "11",  true  },
        { "000", false },
        { "001", true  },
        { "010", true  },
        { "100", true  },
        { "101", true  },
        { "111", true  }
    };
    const size_t NUM_DATA_ODD = sizeof DATA_ODD / sizeof *DATA_ODD;

    for (size_t i = 0; i < NUM_DATA_ODD; ++i) {
        const char *const SPEC = DATA_ODD[i].d_spec_p;
        const VALUE       EXP  =
            bsltf::TemplateTestFacility::create<VALUE>(DATA_ODD[i].d_result);

            bsltf::TestValuesArray<VALUE> values(SPEC);
            ASSERT((EXP ==
                          bsl::any_of(values.begin(), values.end(), IsOdd())));
    }
}

template <class VALUE>
void runTestNoneOf()
    // Test driver for 'none_of'.
{
    const struct {
        const char *d_spec_p;
        bool        d_result;
    } DATA_EVEN[] = {
        { "",    true  },
        { "0",   false },
        { "1",   true  },
        { "00",  false },
        { "01",  false },
        { "10",  false },
        { "11",  true  },
        { "000", false },
        { "001", false },
        { "010", false },
        { "100", false },
        { "101", false },
        { "111", true  }
    };
    const size_t NUM_DATA_EVEN = sizeof DATA_EVEN / sizeof *DATA_EVEN;

    for (size_t i = 0; i < NUM_DATA_EVEN; ++i) {
        const char *const SPEC = DATA_EVEN[i].d_spec_p;
        const VALUE       EXP  =
            bsltf::TemplateTestFacility::create<VALUE>(DATA_EVEN[i].d_result);

            bsltf::TestValuesArray<VALUE> values(SPEC);
            ASSERT((EXP ==
                          bsl::none_of(values.begin(), values.end(), isEven)));
    }

    const struct {
        const char *d_spec_p;
        bool        d_result;
    } DATA_ODD[] = {
        { "",    true  },
        { "0",   true  },
        { "1",   false },
        { "00",  true  },
        { "01",  false },
        { "10",  false },
        { "11",  false },
        { "000", true  },
        { "001", false },
        { "010", false },
        { "100", false },
        { "101", false },
        { "111", false }
    };
    const size_t NUM_DATA_ODD = sizeof DATA_ODD / sizeof *DATA_ODD;

    for (size_t i = 0; i < NUM_DATA_ODD; ++i) {
        const char *const SPEC = DATA_ODD[i].d_spec_p;
        const VALUE       EXP  =
            bsltf::TemplateTestFacility::create<VALUE>(DATA_ODD[i].d_result);

            bsltf::TestValuesArray<VALUE> values(SPEC);
            ASSERT((EXP ==
                         bsl::none_of(values.begin(), values.end(), IsOdd())));
    }
}

#endif

// ============================================================================
//                            MAIN PROGRAM
// ----------------------------------------------------------------------------

int main(int argc, char *argv[])
{
    int test = argc > 1 ? atoi(argv[1]) : 0;

                verbose = argc > 2;
            veryVerbose = argc > 3;
        veryVeryVerbose = argc > 4;
    veryVeryVeryVerbose = argc > 5;

    printf("TEST " __FILE__ " CASE %d\n", test);

    switch (test) { case 0:
      case 1: {
        // --------------------------------------------------------------------
        // FUNCTIONALITY TEST
        //
        // Concerns:
        //: 1 That the routines exist in the 'bsl' namespace and behave as
        //    expected.
        //
        // Plan:
        //: 1 Run each method with an empty input range and verify that the
        //:   behavior is as expected.
        //: 2 Run each method with a single-element input range and verify that
        //:   the behavior is as expected.
        //: 3 Run each method with multiple-element input range and verify that
        //:   the behavior is as expected.
        //
        // Testing:
        //   bool all_of (InputIter first, InputIter last, PREDICATE pred);
        //   bool any_of (InputIter first, InputIter last, PREDICATE pred);
        //   bool none_of(InputIter first, InputIter last, PREDICATE pred);
        // --------------------------------------------------------------------

        if (verbose) printf("\nFUNCTIONALITY TEST"
                            "\n==================\n");

#ifndef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
        runTestAllOf<char>();
        runTestAnyOf<char>();
        runTestNoneOf<char>();
#endif

      } break;
      default: {
        fprintf(stderr, "WARNING: CASE `%d' NOT FOUND.\n", test);
        testStatus = -1;
      }
    }

    if (testStatus > 0) {
        fprintf(stderr, "Error, non-zero test status = %d.\n", testStatus);
    }
    return testStatus;
}

// ----------------------------------------------------------------------------
// Copyright 2020 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------
<|endoftext|>


<commit_before>#include <mlopen/hipoc_program.hpp>
#include <mlopen/kernel.hpp>
#include <mlopen/errors.hpp>

#include <unistd.h>

namespace mlopen {

std::string GetFileName(const HIPOCProgram::FilePtr& f)
{
    auto fd = fileno(f.get());
    std::string path = "/proc/self/fd/" + std::to_string(fd);
    std::array<char, 256> buffer{};
    readlink(path.c_str(), buffer.data(), buffer.size());
    return buffer.data();
}

hipModulePtr CreateModule(const std::string& program_name, std::string params)
{
    HIPOCProgram::FilePtr tmpsrc{std::tmpfile()};
    std::string src = GetKernelSrc(program_name);
    std::string src_name = GetFileName(tmpsrc);

    if (std::fwrite(src.c_str(), 1, src.size(), tmpsrc.get()) != src.size())
        MLOPEN_THROW("Failed to write to src file");

    std::system((HIP_OC_COMPILER +
        std::string(" -march=hsail64 -mdevice=Fiji -cl-denorms-are-zero -save-temps=dump -nobin ") +
        params + " " +
        src_name).c_str());

    std::string obj_file = src_name + "_obj";

    std::system((HIP_OC_FINALIZER +
        std::string("-target=8:0:3 -hsail dump_0_Fiji.hsail -output=") +
        obj_file
    ).c_str());

    hipModule_t raw_m;
    auto status = hipModuleLoad(&raw_m, obj_file.c_str());
    hipModulePtr m{raw_m};
    std::remove(obj_file.c_str());
    if (status != hipSuccess) MLOPEN_THROW("Failed creating module");
    return m;
}

HIPOCProgram::HIPOCProgram()
{}
HIPOCProgram::HIPOCProgram(const std::string &program_name, std::string params)
{
    this->module = CreateModule(program_name, params);
}
}
<commit_msg>Log commands<commit_after>#include <mlopen/hipoc_program.hpp>
#include <mlopen/kernel.hpp>
#include <mlopen/errors.hpp>

#include <unistd.h>

namespace mlopen {

void execute(std::string s)
{
    std::cout << s << std::endl;
    std::system(s.c_str());
}

std::string quote(std::string s)
{
    return '"' + s + '"';
}

std::string GetFileName(const HIPOCProgram::FilePtr& f)
{
    auto fd = fileno(f.get());
    std::string path = "/proc/self/fd/" + std::to_string(fd);
    std::array<char, 256> buffer{};
    if (readlink(path.c_str(), buffer.data(), buffer.size()-1) == -1)
        MLOPEN_THROW("Error reading filename");
    return buffer.data();
}

hipModulePtr CreateModule(const std::string& program_name, std::string params)
{
    HIPOCProgram::FilePtr tmpsrc{std::tmpfile()};
    std::string src = GetKernelSrc(program_name);
    std::string src_name = GetFileName(tmpsrc);

    if (std::fwrite(src.c_str(), 1, src.size(), tmpsrc.get()) != src.size())
        MLOPEN_THROW("Failed to write to src file");

    execute(HIP_OC_COMPILER +
        std::string(" -march=hsail64 -mdevice=Fiji -cl-denorms-are-zero -save-temps=dump -nobin ") +
        params + " " +
        quote(src_name));

    std::string obj_file = src_name + "_obj";

    execute(HIP_OC_FINALIZER +
        std::string(" -target=8:0:3 -hsail dump_0_Fiji.hsail -output=") +
        quote(obj_file)
    );

    hipModule_t raw_m;
    auto status = hipModuleLoad(&raw_m, obj_file.c_str());
    hipModulePtr m{raw_m};
    std::remove(obj_file.c_str());
    if (status != hipSuccess) MLOPEN_THROW("Failed creating module");
    return m;
}

HIPOCProgram::HIPOCProgram()
{}
HIPOCProgram::HIPOCProgram(const std::string &program_name, std::string params)
{
    this->module = CreateModule(program_name, params);
}
}
<|endoftext|>


<commit_before>//   Copyright 2015 Patrick Putnam
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
#ifndef CLOTHO_NEUTRAL_ALLELE_HPP_
#define CLOTHO_NEUTRAL_ALLELE_HPP_

#include "clotho/data_spaces/allele_space/base_allele.hpp"

#include "clotho/utility/state_object.hpp"
#include "clotho/utility/log_helper.hpp"

#include "clotho/utility/bit_helper.hpp"

namespace clotho {
namespace genetics {

template < class PositionType >
class neutral_allele_vectorized : public base_allele_vectorized< PositionType > {
public:
    typedef base_allele_vectorized< PositionType >      base_type;
    typedef neutral_allele_vectorized< PositionType >   self_type;

    typedef unsigned long long                          block_type;
    typedef block_type *                                neutrality_vector_type;

    typedef clotho::utility::BitHelper< block_type >    bit_helper_type;

    neutral_allele_vectorized( size_t a = 0 ) :
        base_type( a )
        , m_neutral( NULL )
        , m_block_size(0)
        , m_block_alloc(0)
    {
        this->grow( a );
    }

    bool getNeutralAt( size_t index ) const {
        assert( 0 <= index && index < this->m_pos_size );

        size_t bidx = index / bit_helper_type::BITS_PER_BLOCK;
        block_type bmask = bit_helper_type::bit_offset(index);

        return m_neutral[ bidx ] & bmask;
    }

    void setNeutralAt( size_t index, bool neu ) {
        assert( 0 <= index && index < this->m_pos_size );

        size_t bidx = index / bit_helper_type::BITS_PER_BLOCK;
        block_type mask = bit_helper_type::bit_offset(index);

        if( ((m_neutral[ bidx ] & mask) == mask) != neu )
            m_neutral[ bidx ] ^= mask;
    }

//    bool getNeutralAt( size_t index ) const {
//        return m_neutral[ index ];
//    }
//
//    void setNeutralAt( size_t index, bool neu ) {
//        if( index >= base_type::size() ) {
//            resize( index + 1 );
//        }
//
//        m_neutral[ index ] = neu;
//    }

//    bool isAllNeutral() const {
//        const_neutrality_iterator first = m_neutral.begin(), last = this->m_neutral.end();
//        bool all_neutral = true;
//        while( all_neutral && first != last ) {
//            all_neutral = *first++;
//        }
//
//        return all_neutral;
//    }
    bool isAllNeutral() const {
        for( size_t i = 0; i < m_block_size - 1; ++i ) {
            if( m_neutral[i] != bit_helper_type::ALL_SET )
                return false;
        }

        block_type mask = bit_helper_type::low_bit_mask( this->m_pos_size - 1 );

//        std::cerr << "Comparing: " << std::hex << m_neutral[m_block_size - 1] << " to " << mask << std::dec << std::endl;

//        std::cerr << "Checking: " << (m_block_size - 1) << std::endl;

        return m_neutral[m_block_size - 1] == mask;
    }

    void inherit( self_type & parent ) {
        // inherit positions
        assert( parent.size() <= this->size() );
        memcpy( this->m_positions, parent.m_positions, parent.size() * sizeof(typename base_type::base_type::position_type) );

        // inherit neutral
        assert( parent.m_block_size < this->m_block_alloc );
        std::copy( parent.m_neutral, parent.m_neutral + parent.m_block_size, this->m_neutral );
    }

//    neutrality_iterator neutral_begin() {
//        return m_neutral.begin();
//    }
//
//    neutrality_iterator neutral_end() {
//        return m_neutral.end();
//    }
//
//    const_neutrality_iterator neutral_begin() const {
//        return m_neutral.begin();
//    }
//
//    const_neutrality_iterator neutral_end() const {
//        return m_neutral.end();
//    }

    void push_back( self_type & other, size_t idx ) {
        size_t e = this->size();

        this->resize( e + 1 );

        this->setPositionAt( e, other.getPositionAt( idx ) );
        this->setNeutralAt( e, other.getNeutralAt( idx ) );
    }

    virtual size_t grow( size_t rows ) {
        this->resize( rows );

        return this->size();
    }

    virtual ~neutral_allele_vectorized() {
        if( m_neutral != NULL ) {
            delete [] m_neutral;
        }
    }

protected:

    virtual void resize( size_t s ) {
        base_type::resize( s );

        size_t bc = bit_helper_type::padded_block_count( s );
        if( bc > m_block_alloc ) {
            if( m_neutral != NULL ) {
                delete [] m_neutral;
            }

            m_neutral = new block_type[ bc ];
            m_block_alloc = bc;

        }

        memset( m_neutral, 0, m_block_alloc * sizeof(block_type));
        m_block_size = bc;
    }

    neutrality_vector_type  m_neutral;
    size_t m_block_size, m_block_alloc;
};

}   // namespace genetics
}   // namespace clotho

namespace clotho {
namespace utility {

template < class PositionType >
struct state_getter< clotho::genetics::neutral_allele_vectorized< PositionType > > {
    typedef clotho::genetics::neutral_allele_vectorized< PositionType > object_type;

    void operator()( boost::property_tree::ptree & s, object_type & obj ) {
        size_t all_count = obj.allele_count();
        size_t i = 0;
        while( i < all_count ) {
            boost::property_tree::ptree all;
            all.put( "position", obj.getPositionAt(i) );
            all.put( "neutral", obj.getNeutralAt(i) );

            s.push_back( std::make_pair("", all ) );
            ++i;
        }

    }
};

}   // namespace utility
}   // namespace clotho

#endif  // CLOTHO_NEUTRAL_ALLELE_HPP_
<commit_msg>Correcting block calculation<commit_after>//   Copyright 2015 Patrick Putnam
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
#ifndef CLOTHO_NEUTRAL_ALLELE_HPP_
#define CLOTHO_NEUTRAL_ALLELE_HPP_

#include "clotho/data_spaces/allele_space/base_allele.hpp"

#include "clotho/utility/state_object.hpp"
#include "clotho/utility/log_helper.hpp"

#include "clotho/utility/bit_helper.hpp"

namespace clotho {
namespace genetics {

template < class PositionType >
class neutral_allele_vectorized : public base_allele_vectorized< PositionType > {
public:
    typedef base_allele_vectorized< PositionType >      base_type;
    typedef neutral_allele_vectorized< PositionType >   self_type;

    typedef unsigned long long                          block_type;
    typedef block_type *                                neutrality_vector_type;

    typedef clotho::utility::BitHelper< block_type >    bit_helper_type;

    neutral_allele_vectorized( size_t a = 0 ) :
        base_type( a )
        , m_neutral( NULL )
        , m_block_size(0)
        , m_block_alloc(0)
    {
        this->grow( a );
    }

    bool getNeutralAt( size_t index ) const {
        assert( 0 <= index && index < this->m_pos_size );

        size_t bidx = index / bit_helper_type::BITS_PER_BLOCK;
        block_type bmask = bit_helper_type::bit_offset(index);

        return m_neutral[ bidx ] & bmask;
    }

    void setNeutralAt( size_t index, bool neu ) {
        assert( 0 <= index && index < this->m_pos_size );

        size_t bidx = index / bit_helper_type::BITS_PER_BLOCK;
        block_type mask = bit_helper_type::bit_offset(index);

        if( ((m_neutral[ bidx ] & mask) == mask) != neu )
            m_neutral[ bidx ] ^= mask;
    }

//    bool getNeutralAt( size_t index ) const {
//        return m_neutral[ index ];
//    }
//
//    void setNeutralAt( size_t index, bool neu ) {
//        if( index >= base_type::size() ) {
//            resize( index + 1 );
//        }
//
//        m_neutral[ index ] = neu;
//    }

//    bool isAllNeutral() const {
//        const_neutrality_iterator first = m_neutral.begin(), last = this->m_neutral.end();
//        bool all_neutral = true;
//        while( all_neutral && first != last ) {
//            all_neutral = *first++;
//        }
//
//        return all_neutral;
//    }
    bool isAllNeutral() const {
        size_t N = (this->m_pos_size - 1) / bit_helper_type::BITS_PER_BLOCK;
        assert( N < m_block_size );
        for( size_t i = 0; i < N; ++i ) {
            if( m_neutral[i] != bit_helper_type::ALL_SET )
                return false;
        }

        block_type mask = bit_helper_type::low_bit_mask( this->m_pos_size - 1 );

//        std::cerr << "Comparing: " << std::hex << m_neutral[m_block_size - 1] << " to " << mask << std::dec << std::endl;

//        std::cerr << "Checking: " << (m_block_size - 1) << std::endl;

        return m_neutral[N] == mask;
    }

    void inherit( self_type & parent ) {
        // inherit positions
        assert( parent.size() <= this->size() );
        memcpy( this->m_positions, parent.m_positions, parent.size() * sizeof(typename base_type::base_type::position_type) );

        // inherit neutral
        assert( parent.m_block_size < this->m_block_alloc );
        std::copy( parent.m_neutral, parent.m_neutral + parent.m_block_size, this->m_neutral );
    }

//    neutrality_iterator neutral_begin() {
//        return m_neutral.begin();
//    }
//
//    neutrality_iterator neutral_end() {
//        return m_neutral.end();
//    }
//
//    const_neutrality_iterator neutral_begin() const {
//        return m_neutral.begin();
//    }
//
//    const_neutrality_iterator neutral_end() const {
//        return m_neutral.end();
//    }

    void push_back( self_type & other, size_t idx ) {
        size_t e = this->size();

        this->resize( e + 1 );

        this->setPositionAt( e, other.getPositionAt( idx ) );
        this->setNeutralAt( e, other.getNeutralAt( idx ) );
    }

    virtual size_t grow( size_t rows ) {
        this->resize( rows );

        return this->size();
    }

    virtual ~neutral_allele_vectorized() {
        if( m_neutral != NULL ) {
            delete [] m_neutral;
        }
    }

protected:

    virtual void resize( size_t s ) {
        base_type::resize( s );

        size_t bc = bit_helper_type::padded_block_count( s );
        if( bc > m_block_alloc ) {
            if( m_neutral != NULL ) {
                delete [] m_neutral;
            }

            m_neutral = new block_type[ bc ];
            m_block_alloc = bc;

        }

        memset( m_neutral, 0, m_block_alloc * sizeof(block_type));
        m_block_size = bc;
    }

    neutrality_vector_type  m_neutral;
    size_t m_block_size, m_block_alloc;
};

}   // namespace genetics
}   // namespace clotho

namespace clotho {
namespace utility {

template < class PositionType >
struct state_getter< clotho::genetics::neutral_allele_vectorized< PositionType > > {
    typedef clotho::genetics::neutral_allele_vectorized< PositionType > object_type;

    void operator()( boost::property_tree::ptree & s, object_type & obj ) {
        size_t all_count = obj.allele_count();
        size_t i = 0;
        while( i < all_count ) {
            boost::property_tree::ptree all;
            all.put( "position", obj.getPositionAt(i) );
            all.put( "neutral", obj.getNeutralAt(i) );

            s.push_back( std::make_pair("", all ) );
            ++i;
        }

    }
};

}   // namespace utility
}   // namespace clotho

#endif  // CLOTHO_NEUTRAL_ALLELE_HPP_
<|endoftext|>