text:
/**
 * GeoDa TM, Copyright (C) 2011-2015 by Luc Anselin - all rights reserved
 *
 * This file is part of GeoDa.
 *
 * GeoDa is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * GeoDa is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <algorithm> // for vector sorting
#include <set>
#include <boost/foreach.hpp>
#include <boost/math/special_functions/fpclassify.hpp>
#include <wx/colour.h>
#include <wx/msgdlg.h>
#include "DbfColContainer.h"
#include "../HighlightState.h"
#include "../GdaConst.h"
#include "../GeneralWxUtils.h"
#include "../GenUtils.h"
#include "../logger.h"
#include "../ShapeOperations/CsvFileUtils.h"
#include "TableState.h"
#include "DbfColContainer.h"

DbfColContainer::DbfColContainer()
: size(0), undefined_initialized(false), raw_data(0),
l_vec(0), d_vec(0), s_vec(0)
{
	info.type = GdaConst::unknown_type;
}

DbfColContainer::~DbfColContainer()
{
	if (IsRawDataAlloc()) FreeRawData();
	FreeVecData();
}

bool DbfColContainer::Init(int size_s,
						   const GdaConst::FieldInfo& field_info_s,
						   bool alloc_raw_data,
						   bool alloc_vector_data,
						   bool mark_all_defined)
{
	if (size_s <= 0) return false;
	if (field_info_s.type == GdaConst::unknown_type ||
		field_info_s.type == GdaConst::placeholder_type) return false;

	info = field_info_s;
	size = size_s;

	stale_min_max_val = true;
	min_val = 0;
	max_val = 0;

	// if mark_all_defined is true, then mark all as begin defined.
	undefined.resize(size_s);
	std::fill(undefined.begin(), undefined.end(), !mark_all_defined);
	undefined_initialized = mark_all_defined;

	if (alloc_raw_data) AllocRawData();
	if (alloc_vector_data) AllocVecData();

	return true;
}

void DbfColContainer::FreeRawData()
{
	if (raw_data) delete [] raw_data; raw_data = 0;
}

void DbfColContainer::AllocRawData()
{
	if (IsRawDataAlloc()) FreeRawData();
	if (info.type != GdaConst::unknown_type &&
		info.type != GdaConst::placeholder_type) {
		raw_data = new char[size * (info.field_len+1)];
	} else {
		raw_data = 0;
	}
}

bool DbfColContainer::IsRawDataAlloc()
{
	return (info.type != GdaConst::unknown_type &&
			info.type != GdaConst::placeholder_type &&
			raw_data);
}

void DbfColContainer::FreeVecData()
{
	if (l_vec) delete [] l_vec; l_vec = 0;
	if (d_vec) delete [] d_vec; d_vec = 0;
	if (s_vec) delete [] s_vec; s_vec = 0;
}

void DbfColContainer::AllocVecData()
{
	if (IsVecDataAlloc()) return;
	if (GetType() == GdaConst::long64_type ||
		GetType() == GdaConst::date_type) {
		l_vec = new wxInt64[size]();
	} else if (GetType() == GdaConst::double_type) {
		d_vec = new double[size]();
	} else if (GetType() == GdaConst::string_type) {
		s_vec = new wxString[size];
	}
}

bool DbfColContainer::IsVecDataAlloc()
{
	if (GetType() == GdaConst::long64_type) {
		return l_vec != 0;
	} else if (GetType() == GdaConst::date_type) {
		return l_vec != 0;
	} else if (GetType() == GdaConst::double_type) {
		return d_vec != 0;
	} else if (GetType() == GdaConst::string_type) {
		return s_vec != 0;
	}
	return false;
}

wxString DbfColContainer::GetName()
{
	return info.name;
}

wxString DbfColContainer::GetDbfColName()
{
	return info.name;
}

GdaConst::FieldType DbfColContainer::GetType()
{
	return info.type;
}

int DbfColContainer::GetFieldLen()
{
	return info.field_len;
}

int DbfColContainer::GetDecimals()
{
	return info.decimals;
}

void DbfColContainer::GetMinMaxVals(double& min_v, double& max_v)
{
	UpdateMinMaxVals();
	min_v = min_val;
	max_v = max_val;
}

void DbfColContainer::UpdateMinMaxVals()
{
	if (GetType() != GdaConst::double_type &&
		GetType() != GdaConst::long64_type) return;
	if (stale_min_max_val) {
		std::vector<double> vals;
		GetVec(vals);
		min_val = vals[0];
		max_val = vals[0];
		for (int i=0; i<size; i++) {
			if (vals[i] < min_val) {
				min_val = vals[i];
			} else if (vals[i] > max_val) {
				max_val = vals[i];
			}
		}
		stale_min_max_val = false;
	}
}

// Change Properties will convert data to vector format if length or
// decimals are changed.
bool DbfColContainer::ChangeProperties(int new_len, int new_dec)
{
	if (!IsRawDataAlloc() && !IsVecDataAlloc()) {
		// this violates the assumption that at least either raw_data
		// exists or a valid vector exists.  This should never happen
		return false;
	}

	if (GetType() == GdaConst::string_type) {
		if (new_len < GdaConst::min_dbf_string_len ||
			new_len > GdaConst::max_dbf_string_len) {
			return false;
		}
		if (IsRawDataAlloc() && !IsVecDataAlloc()) {
			AllocVecData();
			raw_data_to_vec(s_vec);
		}
		// shorten all strings as needed.
		if (new_len < info.field_len) {
			for (int i=0; i<size; i++) {
				if (new_len < s_vec[i].length()) {
					s_vec[i] = s_vec[i].SubString(0, new_len-1);
				}
			}
		}
	} else if (GetType() == GdaConst::long64_type) {
		if (new_len < GdaConst::min_dbf_long_len ||
			new_len > GdaConst::max_dbf_long_len) {
			return false;
		}
		if (IsRawDataAlloc() && !IsVecDataAlloc()) {
			AllocVecData();
			raw_data_to_vec(l_vec);
		}
		// limit all vector values to acceptable range
		//wxInt64 max_val = DbfFileUtils::GetMaxInt(new_len);
		//wxInt64 min_val = DbfFileUtils::GetMinInt(new_len);
		//for (int i=0; i<size; i++) {
		//	if (max_val < l_vec[i]) {
		//		l_vec[i] = max_val;
		//	} else if (min_val > l_vec[i]) {
		//		l_vec[i] = min_val;
		//	}
		//}
	} else if (GetType() == GdaConst::double_type) {
		if (new_len < GdaConst::min_dbf_double_len ||
			new_len > GdaConst::max_dbf_double_len ||
			new_dec < GdaConst::min_dbf_double_decimals ||
			new_dec > GdaConst::max_dbf_double_decimals) {
			return false;
		}
		int suggest_len;
		int suggest_dec;
		DbfFileUtils::SuggestDoubleParams(new_len, new_dec,
										  &suggest_len, &suggest_dec);
		if (new_len != suggest_len || new_dec != suggest_dec) {
			return false;
		}
		if (IsRawDataAlloc() && !IsVecDataAlloc()) {
			AllocVecData();
			raw_data_to_vec(d_vec);
		}
		// limit all vectors to acceptable range
		//double max_val = DbfFileUtils::GetMaxDouble(new_len, new_dec);
		//double min_val = DbfFileUtils::GetMinDouble(new_len, new_dec);
		//for (int i=0, iend=size; i != iend; i++) {
		//	if (max_val < d_vec[i]) {
		//		d_vec[i] = max_val;
		//	} else if (min_val > d_vec[i]) {
		//		d_vec[i] = min_val;
		//	}
		//}
		info.decimals = new_dec;
	} else { // GdaConst::date_type
		// can only change field name for date_type
		if (new_len != GdaConst::max_dbf_date_len) return false;
	}

	if (IsRawDataAlloc()) FreeRawData();
	info.field_len = new_len;
	return true;
}

bool DbfColContainer::ChangeName(const wxString& new_name)
{
	if (!DbfFileUtils::isValidFieldName(new_name)) return false;
	info.name = new_name;
	return true;
}

bool DbfColContainer::sprintf_period_for_decimal()
{
	char buf[10];
	sprintf(buf, "%#3.1f", 2.5);
	//LOG_MSG(wxString::Format("DbfColContainer::sprintf_period_for_decimal()"
	//						 " = %s", buf[1] == '.' ? "true" : "false"));
	return buf[1] == '.';
}

// Allow for filling of double from long64 field
void DbfColContainer::GetVec(std::vector<double>& vec)
{
	if (GetType() != GdaConst::double_type &&
		GetType() != GdaConst::long64_type) return;
	if (!IsVecDataAlloc() && IsRawDataAlloc()) CopyRawDataToVector();
	if (vec.size() != size) vec.resize(size);
	if (GetType() == GdaConst::double_type) {
		if (IsVecDataAlloc()) {
			for (int i=0; i<size; i++) vec[i] = d_vec[i];
		} else {
			raw_data_to_vec(vec);
		}
	} else {
		if (IsVecDataAlloc()) {
			for (int i=0; i<size; i++) vec[i] = (double) l_vec[i];
		} else {
			std::vector<wxInt64> t(size);
			raw_data_to_vec(t);
			for (int i=0; i<size; i++) vec[i] = (double) t[i];
		}
	}
}

// Allow for filling of long64 from double field
void DbfColContainer::GetVec(std::vector<wxInt64>& vec)
{
	if (GetType() != GdaConst::double_type &&
		GetType() != GdaConst::long64_type &&
        GetType() != GdaConst::date_type ) return;
	if (!IsVecDataAlloc() && IsRawDataAlloc()) CopyRawDataToVector();
	if (vec.size() != size) vec.resize(size);
	if (GetType() == GdaConst::long64_type ||
        GetType() == GdaConst::date_type ) {
		if (IsVecDataAlloc()) {
			for (int i=0; i<size; i++) vec[i] = l_vec[i];
		} else {
			raw_data_to_vec(vec);
		}
	} else {
		if (IsVecDataAlloc()) {
			for (int i=0; i<size; i++) vec[i] = (wxInt64) d_vec[i];
		} else {
			std::vector<double> t(size);
			raw_data_to_vec(t);
			for (int i=0; i<size; i++) vec[i] = (wxInt64) t[i];
		}
	}
}

void DbfColContainer::GetVec(std::vector<wxString>& vec)
{
	if (vec.size() != size) vec.resize(size);
	if (IsVecDataAlloc()) {
		for (int i=0; i<size; i++) vec[i] = s_vec[i];
	} else {
		raw_data_to_vec(vec);
	}
}

void DbfColContainer::SetFromVec(const std::vector<double>& vec)
{
	if (vec.size() != size) return;
	if (GetType() != GdaConst::long64_type &&
		GetType() != GdaConst::double_type) return;
	if (!IsVecDataAlloc()) AllocVecData();
	if (IsRawDataAlloc()) FreeRawData();

	CheckUndefined();
	for (int i=0; i<size; i++) {
		undefined[i] = !boost::math::isfinite<double>(vec[i]);
	}
	undefined_initialized = true;

	if (GetType() == GdaConst::long64_type) {
		for (int i=0; i<size; i++) {
			l_vec[i] = undefined[i] ? 0 : (wxInt64) vec[i];
		}
	} else { // must be double_type
		for (int i=0; i<size; i++) {
			d_vec[i] = undefined[i] ? 0 : vec[i];
		}
	}
	stale_min_max_val = true;
	UpdateMinMaxVals();
}

void DbfColContainer::SetFromVec(const std::vector<wxInt64>& vec)
{
	if (vec.size() != size) return;
	if (GetType() != GdaConst::long64_type &&
		GetType() != GdaConst::double_type) return;
	if (!IsVecDataAlloc()) AllocVecData();
	if (IsRawDataAlloc()) FreeRawData();

	CheckUndefined();
	for (int i=0; i<size; i++) undefined[i] = false;
	undefined_initialized = true;
	if (GetType() == GdaConst::long64_type) {
		for (int i=0; i<size; i++) l_vec[i] = vec[i];
	} else { // must be double_type
		for (int i=0; i<size; i++) d_vec[i] = (double) vec[i];
	}
	stale_min_max_val = true;
	UpdateMinMaxVals();
}

void DbfColContainer::SetFromVec(const std::vector<wxString>& vec)
{
	if (vec.size() != size) return;
	if (!IsVecDataAlloc()) AllocVecData();
	if (IsRawDataAlloc()) FreeRawData();

	for (int i=0; i<size; i++) undefined[i] = false;
	undefined_initialized = true;
	for (int i=0; i<size; i++) s_vec[i] = vec[i];
	stale_min_max_val = false;
}

void DbfColContainer::SetUndefined(const std::vector<bool>& undef_vec)
{
	if (undefined.size() != size) undefined.resize(size);
	CheckUndefined();
	for (int i=0; i<size; i++) undefined[i] = undef_vec[i];
}

void DbfColContainer::GetUndefined(std::vector<bool>& undef_vec)
{
	if (undef_vec.size() != size) undef_vec.resize(size);
	if (!undefined_initialized) CheckUndefined();
	for (int i=0; i<size; i++) undef_vec[i] = undefined[i];
}

void DbfColContainer::CheckUndefined()
{
	if (undefined_initialized) return;
	undefined_initialized = true;
	if (undefined.size() != size) undefined.resize(size);

	if (GetType() == GdaConst::unknown_type ||
		GetType() == GdaConst::placeholder_type) return;
	const int inc = info.field_len+1;
	for (int i=0; i<size; i++) undefined[i] = false;
	if (GetType() == GdaConst::double_type) {
		if (IsRawDataAlloc()) {
			char* buf=raw_data;
			for (int i=0; i<size; i++) {
				// we are not using atof since we it seems to be difficult
				// to choose a US locale on all systems so as to assume the
				// DBF-required use of '.' for the decimal character
				wxString temp(buf);
				temp.Trim(true);
				temp.Trim(false);
				double x;
				bool r = temp.ToCDouble(&x);
				undefined[i] = !(r && boost::math::isfinite<double>(x));
				buf += inc;
			}
		} else {
			for (int i=0; i<size; i++) {
				undefined[i]=!boost::math::isfinite<double>(d_vec[i]);
			}
		}
	} else if (GetType() == GdaConst::long64_type) {
		if (IsRawDataAlloc()) {
			char* buf=raw_data;
			for (int i=0; i<size; i++) {
				undefined[i] = !GenUtils::validInt(buf);
				buf += inc;
			}
		} else {
			// all integers are valid, there is no way to
			// represent infinity or NaN as in float and double
		}
	}
}

void DbfColContainer::raw_data_to_vec(std::vector<double>& vec)
{
	if (vec.size() != size) {
		vec.resize(size);
		std::fill(vec.begin(), vec.end(), 0);
	}
	if (GetType() == GdaConst::unknown_type ||
		GetType() == GdaConst::placeholder_type) return;
	CheckUndefined();
	const int inc = info.field_len+1;
	char* buf=raw_data;
	for (int i=0; i<size; i++) {
		// we are not using atof since we it seems to be difficult
		// to choose a US locale on all systems so as to assume the
		// DBF-required use of '.' for the decimal character
		wxString temp(buf);
		temp.Trim(true);
		temp.Trim(false);
		bool r = temp.ToCDouble(&vec[i]);
		undefined[i] = !(r && boost::math::isfinite<double>(vec[i]));
		buf += inc;
	}
}

void DbfColContainer::raw_data_to_vec(double* vec)
{
	if (!vec) return;
	if (GetType() == GdaConst::unknown_type ||
		GetType() == GdaConst::placeholder_type) return;
	CheckUndefined();
	const int inc = info.field_len+1;
	char* buf=raw_data;
	for (int i=0; i<size; i++) {
		// we are not using atof since we it seems to be difficult
		// to choose a US locale on all systems so as to assume the
		// DBF-required use of '.' for the decimal character
		wxString temp(buf);
		temp.Trim(true);
		temp.Trim(false);
		vec[i] = 0;
		bool r = temp.ToCDouble(&vec[i]);
		undefined[i] = !(r && boost::math::isfinite<double>(vec[i]));
		buf += inc;
	}
}

void DbfColContainer::raw_data_to_vec(std::vector<wxInt64>& vec)
{
	if (vec.size() != size) {
		vec.resize(size);
		std::fill(vec.begin(), vec.end(), 0);
	}
	if (GetType() == GdaConst::unknown_type ||
		GetType() == GdaConst::placeholder_type) return;
	CheckUndefined();
	const int inc = info.field_len+1;
	char* buf=raw_data;
	for (int i=0; i<size; i++) {
		undefined[i] = !GenUtils::validInt(buf);
		GenUtils::strToInt64(buf, &vec[i]);  // will set to 0 if undefined
		buf += inc;
	}
}

void DbfColContainer::raw_data_to_vec(wxInt64* vec)
{
	if (!vec) return;
	if (GetType() == GdaConst::unknown_type ||
		GetType() == GdaConst::placeholder_type) return;
	CheckUndefined();
	const int inc = info.field_len+1;
	char* buf=raw_data;
	for (int i=0; i<size; i++) {
		undefined[i] = !GenUtils::validInt(buf);
		vec[i] = 0;
		GenUtils::strToInt64(buf, &vec[i]);  // will set to 0 if undefined
		buf += inc;
	}
}

void DbfColContainer::raw_data_to_vec(std::vector<wxString>& vec)
{
	if (vec.size() != size) vec.resize(size);
	if (GetType() == GdaConst::unknown_type ||
		GetType() == GdaConst::placeholder_type) return;
	CheckUndefined();
	const int inc = info.field_len+1;
	char* buf=raw_data;
	for (int i=0; i<size; i++) {
		vec[i] = wxString(buf);
		undefined[i] = false;
		buf += inc;
	}
}

void DbfColContainer::raw_data_to_vec(wxString* vec)
{
	if (!vec) return;
	if (GetType() == GdaConst::unknown_type ||
		GetType() == GdaConst::placeholder_type) return;
	CheckUndefined();
	const int inc = info.field_len+1;
	char* buf=raw_data;
	for (int i=0; i<size; i++) {
		vec[i] = wxString(buf);
		undefined[i] = false;
		buf += inc;
	}
}

void DbfColContainer::d_vec_to_raw_data()
{
	char temp[255];
	if (GetType() == GdaConst::unknown_type ||
		GetType() == GdaConst::placeholder_type) return;
	const int inc = info.field_len+1;
	char* buf=raw_data;
	for (int i=0; i<size; i++) {
		if (!boost::math::isfinite<double>(d_vec[i])) {
			// the number is either NaN (not a number) or +/- infinity
			undefined[i] = true;
		}
		if (undefined[i]) {
			for (int j=0; j<info.field_len; j++) buf[j] = ' ';
		} else {
			sprintf(temp, "%#*.*f", info.field_len,
					info.decimals, d_vec[i]);
			for (int j=0; j<info.field_len; j++) buf[j] = temp[j];
		}
		buf[info.field_len] = '\0';
		buf += inc;
	}
	if (!sprintf_period_for_decimal()) {
		for (int i=0, iend=size*inc; i<iend; i++) {
			if (raw_data[i] == ',') raw_data[i] = '.';
		}
	}
}

void DbfColContainer::l_vec_to_raw_data()
{
	char temp[255];
	if (GetType() == GdaConst::unknown_type ||
		GetType() == GdaConst::placeholder_type) return;
	const int inc = info.field_len+1;
	char* buf=raw_data;
	for (int i=0; i<size; i++) {
		if (undefined[i]) {
			for (int j=0; j<info.field_len; j++) buf[j] = ' ';
		} else {
			sprintf(temp, "%*lld", info.field_len, l_vec[i]);
			for (int j=0; j<info.field_len; j++) buf[j] = temp[j];
		}
		buf[info.field_len] = '\0';
		buf += inc;
	}
}

void DbfColContainer::s_vec_to_raw_data()
{
	char temp[255];
	if (GetType() == GdaConst::unknown_type ||
		GetType() == GdaConst::placeholder_type) return;
	const int inc = info.field_len+1;
	char* buf=raw_data;
	for (int i=0; i<size; i++) {
		if (undefined[i] || s_vec[i].IsEmpty()) {
			for (int j=0; j<info.field_len; j++) buf[j] = ' ';
		} else {
			sprintf(temp, "%*s", info.field_len,
					(const_cast<char*>((const char*)s_vec[i].mb_str())));
			for (int j=0; j<info.field_len; j++) buf[j] = temp[j];
		}
		buf[info.field_len] = '\0';
		buf += inc;
	}
}

void DbfColContainer::CopyRawDataToVector()
{
	if (!IsRawDataAlloc()) return;
	if (!IsVecDataAlloc()) AllocVecData();
	switch (GetType()) {
		case GdaConst::date_type:
			raw_data_to_vec(l_vec);
			break;
		case GdaConst::long64_type:
			raw_data_to_vec(l_vec);
			break;
		case GdaConst::double_type:
			raw_data_to_vec(d_vec);
			break;
		case GdaConst::string_type:
			raw_data_to_vec(s_vec);
			break;
		default:
			break;
	}
}

void DbfColContainer::CopyVectorToRawData()
{
	if (!IsVecDataAlloc()) return;
	if (!IsRawDataAlloc()) AllocRawData();
	switch (GetType()) {
		case GdaConst::date_type:
		{
			l_vec_to_raw_data();
		}
			break;
		case GdaConst::long64_type:
		{
			l_vec_to_raw_data();
		}
			break;
		case GdaConst::double_type:
		{
			d_vec_to_raw_data();
		}
			break;
		case GdaConst::string_type:
		{
			s_vec_to_raw_data();
		}
			break;
		default:
			break;
	}
}

max_stars_repo_name: chenyoujie/GeoDa

max_issues_repo_name: chenyoujie/GeoDa

max_forks_repo_name: chenyoujie/GeoDa


text:
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/properties.hpp>
#include <boost/graph/dag_shortest_paths.hpp>
#include <boost/graph/depth_first_search.hpp>
#include <boost/graph/edge_list.hpp>
#include <llhelm.hpp>
#include <egraph.hpp>

#ifndef _PARSERS_HEADER_
#define _PARSERS_HEADER_

namespace OptCompiler
{
	namespace SexpParser
	{
		typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, LLHelm*, boost::property<
			boost::vertex_index_t, std::size_t>,
			boost::no_property> Graph;
		typedef boost::graph_traits<Graph>::vertex_descriptor GVertex;
		typedef boost::graph_traits<Graph>::edge_descriptor GEdge;
		typedef std::unordered_map<GVertex, std::string> VTS;
		// For color map
		typedef std::vector<boost::default_color_type>::iterator RAIter;
		typedef boost::vec_adj_list_vertex_id_map<LLHelm*, size_t> ID;
		typedef boost::iterator_property_map<RAIter, ID, std::iterator_traits<RAIter>::value_type, std::iterator_traits<
			RAIter>::reference> CM;

		class Found_vertex_exception : public std::exception
		{
		};

		class bfs_process_visitor : public boost::default_dfs_visitor
		{
		public:
			bfs_process_visitor(GVertex& process, std::vector<std::string>& sq, std::string& im, std::string& rf, std::string& re)
				: vertx(process), outputParts(sq), inputMaterial(im),referFace(rf),referEdge(re)
			{
			}

			void discover_vertex(GVertex u, const Graph& g)
			{
				if (g[u]->get_type() == TYPE_CHOPSAW || g[u]->get_type() == TYPE_BANDSAW || g[u]->get_type() ==
					TYPE_TRACKSAW || g[u]->get_type() == TYPE_JIGSAW)
				{
					vertx = u;
				}
				else if (g[u]->get_type() == TYPE_LUMBER)
				{
					const auto uid = target(*out_edges(u, g).first, g);
					if (g[uid]->get_type() == TYPE_LLHELM)
					{
						inputMaterial = g[uid]->ToString();
						//if (startLumber.empty()) startLumber = inputMaterials.back();
					}
				}
				else if (g[u]->get_type() == TYPE_ASSIGN)
				{
					auto vars = out_edges(u, g);
					vars = out_edges(target(*vars.first, g), g);
					for (auto var = vars.first; var != vars.second; ++var)
					{
						const auto uid = target(*out_edges(target(*var, g), g).first, g);
						outputParts.push_back(g[uid]->ToString());
						//stockQuery[g[uid]->ToString()] = inputMaterials.size();
					}
				}
				else if(g[u]->get_type() == TYPE_FACE)
				{
					const auto uid = target(*out_edges(u, g).first, g);
					if (g[uid]->get_type() == TYPE_LLHELM)
					{
						referFace = g[uid]->ToString();
					}
				}
				else if (g[u]->get_type() == TYPE_EDGE)
				{
					const auto uid = target(*out_edges(u, g).first, g);
					if (g[uid]->get_type() == TYPE_LLHELM)
					{
						referEdge = g[uid]->ToString();
					}
				}
			}

			// std::unordered_map<std::string, int>& stockQuery;
			GVertex& vertx;
			std::vector<std::string>& outputParts;
			std::string& inputMaterial;

			std::string& referFace;
			std::string& referEdge;
		};

		class bfs_ref_visitor : public boost::default_bfs_visitor
		{
		public:
			bfs_ref_visitor(CM& cm, std::pair<bool, Ref*>& r)
				: colorMap(cm), ref(r)
			{
				ref.first = false;
			}

			void discover_vertex(GVertex u, const Graph& g)
			{
				const auto& curType = g[u]->get_type();
				if (curType == TYPE_REFC || curType == TYPE_REFB || curType == TYPE_REFK || curType == TYPE_REFJ || curType == TYPE_REFD)
				{
					ref.first = true;
					ref.second = static_cast<Ref*>(g[u]);
					if (ref.second->IsComplete())
						return;

					typeRef = curType;
				}

				if (curType == TYPE_HEIGHT)
				{
					auto h = target(*out_edges(u, g).first, g);
					h = target(*out_edges(h, g).first, g);
					const auto ht = static_cast<Float*>(g[h]);
					ref.second->height = ht->num;
					ref.second->hasHeight = true;
				}

				if (ref.first)
				{
					if (typeRef == TYPE_REFC)
					{
						if (g[u]->get_type() == TYPE_ANGLE || g[u]->get_type() == TYPE_LENGTH)
						{
							// TODO: more than one?
							const auto var = target(*out_edges(target(*out_edges(u, g).first, g), g).first, g);
							if (g[var]->get_type() == TYPE_FLOAT)
							{
								auto f = static_cast<Float*>(g[var]);
								auto refCont = dynamic_cast<Refc*>(ref.second);
								refCont->values.push_back(f->num);
								refCont->hasValues = true;
							}
						}
					}
					else if (typeRef == TYPE_REFB)
					{
						if (g[u]->get_type() == TYPE_TUPLE)
						{
							boost::graph_traits<Graph>::out_edge_iterator vi, vi_end, next;
							tie(vi, vi_end) = out_edges(u, g);
							for (next = vi; vi != vi_end; vi = next)
							{
								++next;
								auto var = target(*out_edges(target(*vi, g), g).first, g);
								if (g[var]->get_type() == TYPE_FLOAT)
								{
									auto f = dynamic_cast<Float*>(g[var]);
									auto refCont = dynamic_cast<Refb*>(ref.second);
									refCont->values.push_back(f->num);
									refCont->hasValues = true;
								}
							}
						}
					}
					else if (typeRef == TYPE_REFK)
					{
						if (g[u]->get_type() == TYPE_ANGLE || g[u]->get_type() == TYPE_LENGTH)
						{
							// TODO: more than one?
							auto var = target(*out_edges(target(*out_edges(u, g).first, g), g).first, g);
							if (g[var]->get_type() == TYPE_FLOAT)
							{
								auto f = static_cast<Float*>(g[var]);
								auto refCont = dynamic_cast<Refk*>(ref.second);
								refCont->values.push_back(f->num);
								refCont->hasValues = true;
							}
						}
					}
					else if (typeRef == TYPE_REFJ)
					{
						if (g[u]->get_type() == TYPE_TUPLE)
						{
							boost::graph_traits<Graph>::out_edge_iterator vi, vi_end, next;
							tie(vi, vi_end) = out_edges(u, g);
							for (next = vi; vi != vi_end; vi = next)
							{
								++next;
								auto var = target(*out_edges(target(*vi, g), g).first, g);
								if (g[var]->get_type() == TYPE_FLOAT)
								{
									auto f = dynamic_cast<Float*>(g[var]);
									auto refCont = dynamic_cast<Refj*>(ref.second);
									refCont->values.push_back(f->num);
									refCont->hasValues = true;
								}
							}
						}
					}
					else if (typeRef == TYPE_REFD)
					{
						if (g[u]->get_type() == TYPE_TUPLE)
						{
							boost::graph_traits<Graph>::out_edge_iterator vi, vi_end, next;
							tie(vi, vi_end) = out_edges(u, g);
							for (next = vi; vi != vi_end; vi = next)
							{
								++next;
								auto var = target(*out_edges(target(*vi, g), g).first, g);
								if (g[var]->get_type() == TYPE_FLOAT)
								{
									auto f = dynamic_cast<Float*>(g[var]);
									auto refCont = dynamic_cast<Refd*>(ref.second);
									refCont->values.push_back(f->num);
									refCont->hasValues = true;
								}
							}
						}
					}
				}
			}

			void examine_edge(GEdge e, const Graph& g)
			{
				auto targetVertex = target(e, g);

				if (ref.second != nullptr && ref.second->IsComplete())
					put(colorMap, vertex(targetVertex, g), boost::color_traits<Graph>::black());

				if (g[targetVertex]->get_type() == TYPE_CHOPSAW)
				{
					//std::cerr << "we found chop saw" << std::endl;
					//put(colorMap, vertex(targetVertex, g), boost::color_traits<SexpParser::Graph>::black());
				}

				if (g[targetVertex]->get_type() == TYPE_REFC)
				{
					//std::cerr << "we found ref" << std::endl;
				}
			}

			CM& colorMap;
			std::pair<bool, Ref*>& ref;
			Atom typeRef;
		};

		class AST
		{
		public:
			AST() = default;

			void CreateVertex(const GVertex& v, const std::string& str)
			{
				content[v] = str;
			}

			void PreProcess();

			LLHelm* GetProcess() const { return process_; }

			Ref* GetReference() const { return ref_; }

			std::string& GetInputMaterial() { return inputMaterial_; }

			std::vector<std::string>& GetOutputParts() { return outputParts_; }

			std::string& GetReferFace() { return referFace_; }
			std::string& GetReferEdge() { return referEdge_; }

			Graph g;
			VTS content;

		private:
			LLHelm* process_;
			Ref* ref_;
			std::string inputMaterial_;
			std::vector<std::string> outputParts_;
			std::string referFace_;
			std::string referEdge_;
		};

		AST Parse(const std::string& str);

		AST ParseFile(const std::string& filename);
	}

	class EClass;
	class EGraph;

	class EGraphParser
	{
	public:
		typedef std::pair<std::string, std::string> PairStrs;
		typedef std::vector<std::vector<std::vector<PairStrs>>> SubModule;

		static void ParseXML(const std::string& path, std::unordered_map<int, SubModule>& all_progs,
			std::unordered_set<int>& emptyProgs);

		static EClass* ParseEGraph(const std::string& path, EGraph* eg);
	};
}
#endif

ext: hpp

max_stars_repo_name: haisenzhao/CarpentryCompiler

max_issues_repo_name: haisenzhao/CarpentryCompiler

max_forks_repo_name: haisenzhao/CarpentryCompiler


text:
/*! \file
    \brief A reader.

    Copyright (C) 2019-2022 kaoru  https://www.tetengo.org/
*/

#include <cstddef>
#include <stdexcept>
#include <string>

#include <boost/preprocessor.hpp>
#include <boost/test/unit_test.hpp>

#include <tetengo/json/reader.hpp>

namespace
{
    class concrete_reader : public tetengo::json::reader
    {
    public:
        // constructors and destructor

        concrete_reader() : m_values{ "ABC" }, m_index{ 0 } {}

        virtual ~concrete_reader() = default;

    private:
        // variables

        const std::string m_values;

        std::size_t m_index;

        // virtual functions

        virtual bool has_next_impl() const override
        {
            return m_index < m_values.length();
        }

        virtual char peek_impl() const override
        {
            if (m_index >= m_values.length())
            {
                throw std::logic_error{ "The current position is beyond the termination point." };
            }
            return m_values[m_index];
        }

        virtual void next_impl() override
        {
            if (m_index >= m_values.length())
            {
                throw std::logic_error{ "The current position is beyond the termination point." };
            }
            ++m_index;
        }

        virtual const reader& base_reader_impl() const override
        {
            throw std::logic_error{ "No base reader." };
        }
    };

}

BOOST_AUTO_TEST_SUITE(test_tetengo)
BOOST_AUTO_TEST_SUITE(json)
BOOST_AUTO_TEST_SUITE(rader)

BOOST_AUTO_TEST_CASE(construction)
{
    BOOST_TEST_PASSPOINT();

    const concrete_reader reader{};
}

BOOST_AUTO_TEST_CASE(has_next)
{
    BOOST_TEST_PASSPOINT();

    const concrete_reader reader{};

    BOOST_TEST(reader.has_next());
}

BOOST_AUTO_TEST_CASE(peek)
{
    BOOST_TEST_PASSPOINT();

    const concrete_reader reader{};

    BOOST_TEST(reader.peek() == 'A');
}

BOOST_AUTO_TEST_CASE(next)
{
    BOOST_TEST_PASSPOINT();

    concrete_reader reader{};

    BOOST_TEST_REQUIRE(reader.has_next());
    BOOST_TEST(reader.peek() == 'A');
    reader.next();

    BOOST_TEST_REQUIRE(reader.has_next());
    BOOST_TEST(reader.peek() == 'B');
    reader.next();

    BOOST_TEST_REQUIRE(reader.has_next());
    BOOST_TEST(reader.peek() == 'C');
    reader.next();

    BOOST_TEST(!reader.has_next());
    BOOST_CHECK_THROW([[maybe_unused]] const auto& peeked = reader.peek(), std::logic_error);
    BOOST_CHECK_THROW(reader.next(), std::logic_error);
}

BOOST_AUTO_TEST_CASE(base_reader)
{
    BOOST_TEST_PASSPOINT();

    const concrete_reader reader{};

    BOOST_CHECK_THROW([[maybe_unused]] const auto& base_reader = reader.base_reader(), std::logic_error);
}

BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_SUITE_END()

ext: cpp

max_stars_repo_name: tetengo/tetengo

max_issues_repo_name: tetengo/tetengo

max_forks_repo_name: tetengo/tetengo


text:
// Boost.Geometry (aka GGL, Generic Geometry Library)

// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.

// This file was modified by Oracle on 2013, 2015.
// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates.

// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.

// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_GEOMETRY_MULTI_HPP
#define BOOST_GEOMETRY_MULTI_HPP

// keep this file for now, for backward compatibility
// functionality-wise, make it equivalent to boost/geometry/geometry.hpp
#include <boost/geometry/geometry.hpp>

#endif // BOOST_GEOMETRY_MULTI_HPP

max_stars_repo_name: rudylee/expo

max_issues_repo_name: rudylee/expo

max_forks_repo_name: rudylee/expo


text:
/*******************************************************************************
 * wallaroo - A library for configurable creation and wiring of C++ classes.
 * Copyright (C) 2012 Daniele Pallastrelli
 *
 * This file is part of wallaroo.
 * For more information, see http://wallaroo.googlecode.com/
 *
 * Boost Software License - Version 1.0 - August 17th, 2003
 *
 * Permission is hereby granted, free of charge, to any person or organization
 * obtaining a copy of the software and accompanying documentation covered by
 * this license (the "Software") to use, reproduce, display, distribute,
 * execute, and transmit the Software, and to prepare derivative works of the
 * Software, and to permit third-parties to whom the Software is furnished to
 * do so, all subject to the following:
 *
 * The copyright notices in the Software and this entire statement, including
 * the above license grant, this restriction and the following disclaimer,
 * must be included in all copies of the Software, in whole or in part, and
 * all derivative works of the Software, unless such copies or derivative
 * works are solely in the form of machine-executable object code generated by
 * a source language processor.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
 * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
 * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 ******************************************************************************/

#include <boost/test/unit_test.hpp>

#include "wallaroo/registered.h"
#include "wallaroo/catalog.h"
#include "wallaroo/cxx0x.h"
#include "wallaroo/jsonconfiguration.h"
#include "wallaroo/xmlconfiguration.h"

using namespace wallaroo;
using namespace cxx0x;

// class with attributes:

struct A7 : public Part
{
    A7() :
        strAtt( "str_attr", RegistrationToken() ),
        strAtt2( "str_attr_2", RegistrationToken() ),
        cintAtt( "c_int_attr", RegistrationToken() ),
        intAtt( "int_attr", RegistrationToken( ) ),
        ulAtt( "ul_attr", RegistrationToken() ),
        boolAtt( "bool_attr", RegistrationToken() )
    {}
    virtual ~A7() {}

    Attribute< std::string > strAtt;
    Attribute< std::string > strAtt2;
    const Attribute< int > cintAtt;
    Attribute< int > intAtt;
    Attribute< unsigned long > ulAtt;
    Attribute< bool > boolAtt;
};

WALLAROO_REGISTER( A7 )

struct B7 : public Part
{
    B7() :
        schAtt( "schar_attr", RegistrationToken() ),
        uchAtt( "uchar_attr", RegistrationToken() ),
        ssiAtt( "ssi_attr", RegistrationToken() ),
        usiAtt( "usi_attr", RegistrationToken() ),
        siAtt( "si_attr", RegistrationToken() ),
        uiAtt( "ui_attr", RegistrationToken() ),
        sliAtt( "sli_attr", RegistrationToken() ),
        uliAtt( "uli_attr", RegistrationToken() ),
        fAtt( "f_attr", RegistrationToken() ),
        dAtt( "d_attr", RegistrationToken() ),
        ldAtt( "ld_attr", RegistrationToken() ),
        strAtt( "str_attr", RegistrationToken() ),
        boolAtt( "bool_attr", RegistrationToken() )
    {}
    virtual ~B7() {}

    Attribute< signed char > schAtt;
    Attribute< unsigned char > uchAtt;
    Attribute< signed short int > ssiAtt;
    Attribute< unsigned short int > usiAtt;
    Attribute< signed int > siAtt;
    Attribute< unsigned int > uiAtt;
    Attribute< signed long int > sliAtt;
    Attribute< unsigned long int > uliAtt;
    Attribute< float > fAtt;
    Attribute< double > dAtt;
    Attribute< long double > ldAtt;
    Attribute< std::string > strAtt;
    Attribute< bool > boolAtt;
};

WALLAROO_REGISTER( B7 )

// class to test the Part::Init method
struct C7 : public Part
{
    C7() : ready( false ) {}
    virtual ~C7() {}
    virtual void Init() { ready = true;  }
    bool ready;
};

WALLAROO_REGISTER( C7 )

// tests

BOOST_AUTO_TEST_SUITE( Attributes )

BOOST_AUTO_TEST_CASE( values )
{
    Catalog catalog;
    shared_ptr< A7 > a;

    BOOST_REQUIRE_NO_THROW( a = catalog.Create( "a", "A7" ) );
    BOOST_REQUIRE_NO_THROW( catalog[ "a" ] );

    BOOST_REQUIRE_NO_THROW( set_attribute( "str_attr" ).of( catalog[ "a" ] ).to( std::string( "mystring" ) ) );
    BOOST_REQUIRE_NO_THROW( set_attribute( "str_attr_2" ).of( catalog[ "a" ] ).to( "mystring2" ) );

    wallaroo_within( catalog )
    {
        BOOST_REQUIRE_NO_THROW( set_attribute( "int_attr" ).of( "a" ).to( -123 ) );
        BOOST_REQUIRE_NO_THROW( set_attribute( "ul_attr" ).of( "a" ).to( 123456 ) );
        BOOST_REQUIRE_NO_THROW( set_attribute( "bool_attr" ).of( "a" ).to( false ) );
    }

    // check values

    BOOST_CHECK( a -> strAtt == std::string( "mystring" ) );
    BOOST_CHECK( a -> strAtt2 == std::string( "mystring2" ) );

    BOOST_CHECK( std::string( "mystring" ) == a -> strAtt );
    BOOST_CHECK( std::string( "mystring2" ) == a -> strAtt2 );

    const std::string s1 = a -> strAtt;
    BOOST_CHECK( s1 == "mystring" );
    const std::string s2 = a -> strAtt2;
    BOOST_CHECK( s2 == std::string( "mystring2" ) );

    BOOST_CHECK( a -> intAtt == -123 );
    BOOST_CHECK( a -> ulAtt == 123456 );
    BOOST_CHECK( a -> boolAtt == false );
}

BOOST_AUTO_TEST_CASE( attributeRelationalOperators )
{
    Catalog catalog;
    BOOST_REQUIRE_NO_THROW( catalog.Create( "b", "B7" ) );
    BOOST_REQUIRE_NO_THROW( catalog.Create( "a", "A7" ) );
    BOOST_REQUIRE_NO_THROW( set_attribute( "ui_attr" ).of( catalog[ "b" ] ).to( 50 ) );
    BOOST_REQUIRE_NO_THROW( set_attribute( "ul_attr" ).of( catalog[ "a" ] ).to( 30 ) );

    shared_ptr< B7 > b = catalog[ "b" ];
    shared_ptr< A7 > a = catalog[ "a" ];

    // Attribute VS size_t

    std::size_t x = 30;
    // x < uiAtt
    BOOST_CHECK( x < b->uiAtt );
    BOOST_CHECK( b->uiAtt > x );
    BOOST_CHECK( x <= b->uiAtt );
    BOOST_CHECK( b->uiAtt >= x );
    BOOST_CHECK( x != b->uiAtt );
    BOOST_CHECK( b->uiAtt != x );

    x = 60;
    // x > uiAtt
    BOOST_CHECK( x > b->uiAtt );
    BOOST_CHECK( b->uiAtt < x );
    BOOST_CHECK( x >= b->uiAtt );
    BOOST_CHECK( b->uiAtt <= x );
    BOOST_CHECK( x != b->uiAtt );
    BOOST_CHECK( b->uiAtt != x );

    x = 50;
    // x == uiAtt
    BOOST_CHECK( x == b->uiAtt );
    BOOST_CHECK( b->uiAtt == x );

    // Attribute VS Attribute

    // a->a->ulAtt < b->uiAtt
    BOOST_CHECK( a->ulAtt < b->uiAtt );
    BOOST_CHECK( b->uiAtt > a->ulAtt );
    BOOST_CHECK( a->ulAtt <= b->uiAtt );
    BOOST_CHECK( b->uiAtt >= a->ulAtt );
    BOOST_CHECK( a->ulAtt != b->uiAtt );
    BOOST_CHECK( b->uiAtt != a->ulAtt );

    // a->ulAtt > b->uiAtt
    a->ulAtt = 60;
    BOOST_CHECK( a->ulAtt > b->uiAtt );
    BOOST_CHECK( b->uiAtt < a->ulAtt );
    BOOST_CHECK( a->ulAtt >= b->uiAtt );
    BOOST_CHECK( b->uiAtt <= a->ulAtt );
    BOOST_CHECK( a->ulAtt != b->uiAtt );
    BOOST_CHECK( b->uiAtt != a->ulAtt );

    a->ulAtt = 50;
    // a->ulAtt == uiAtt
    BOOST_CHECK( a->ulAtt == b->uiAtt );
    BOOST_CHECK( b->uiAtt == a->ulAtt );
}

BOOST_AUTO_TEST_CASE( attributeArithmeticOperators )
{
    Catalog catalog;

    BOOST_REQUIRE_NO_THROW( catalog.Create( "a", "A7" ) );
    BOOST_REQUIRE_NO_THROW( catalog[ "a" ] );

    BOOST_REQUIRE_NO_THROW( set_attribute( "str_attr" ).of( catalog[ "a" ] ).to( std::string( "mystring" ) ) );
    BOOST_REQUIRE_NO_THROW( set_attribute( "str_attr_2" ).of( catalog[ "a" ] ).to( "mystring2" ) );

    wallaroo_within( catalog )
    {
        BOOST_REQUIRE_NO_THROW( set_attribute( "c_int_attr" ).of( "a" ).to( -123 ) );
        BOOST_REQUIRE_NO_THROW( set_attribute( "ul_attr" ).of( "a" ).to( 123456 ) );
        BOOST_REQUIRE_NO_THROW( set_attribute( "bool_attr" ).of( "a" ).to( false ) );
    }

    shared_ptr< A7 > a = catalog[ "a" ];

    // check assignment
    BOOST_CHECK_NO_THROW( a -> intAtt = 3 );
    BOOST_CHECK( a -> intAtt == 3 );
    BOOST_CHECK_NO_THROW( a -> strAtt = "foo" );
    BOOST_CHECK( a -> strAtt == std::string( "foo" ) );
    BOOST_CHECK_NO_THROW( a -> boolAtt = true );
    BOOST_CHECK( a -> boolAtt );

    // arithmetic operators
    BOOST_CHECK( ++ a -> intAtt == 4 ); // prefix inc
    BOOST_CHECK( a -> intAtt ++ == 4 ); // postfix inc
    BOOST_CHECK( a -> intAtt == 5 );

    BOOST_CHECK( -- a -> intAtt == 4 ); // prefix dec
    BOOST_CHECK( a -> intAtt -- == 4 ); // postfix dec
    BOOST_CHECK( a -> intAtt == 3 );

    BOOST_CHECK( ( a->intAtt += 2 ) == 5 );
    BOOST_CHECK( a->intAtt == 5 );
    BOOST_CHECK( ( a->intAtt -= 2 ) == 3 );
    BOOST_CHECK( a->intAtt == 3 );
    BOOST_CHECK( ( a->intAtt /= 3 ) == 1 );
    BOOST_CHECK( a->intAtt == 1 );
    BOOST_CHECK( ( a->intAtt *= 3 ) == 3 );
    BOOST_CHECK( a->intAtt == 3 );

    BOOST_CHECK( a->intAtt + 1 == 4 );
    BOOST_CHECK( a->intAtt - 1 == 2 );
    BOOST_CHECK( a->intAtt * 2 == 6 );
    BOOST_CHECK( a->intAtt / 3 == 1 );

    BOOST_CHECK( 1 + a->intAtt == 4 );
    BOOST_CHECK( 3 - a->intAtt == 0 );
    BOOST_CHECK( 2 * a->intAtt == 6 );
    BOOST_CHECK( 3 / a->intAtt == 1 );

    BOOST_CHECK( a->intAtt + a->intAtt == 6 );
    BOOST_CHECK( a->intAtt - a->intAtt == 0 );
    BOOST_CHECK( a->intAtt * a->intAtt == 9 );
    BOOST_CHECK( a->intAtt / a->intAtt == 1 );

    // check some operators with const attribute
    const int x = 123;
    BOOST_CHECK( x + a->cintAtt == 0 );
    BOOST_CHECK( a->ulAtt - x == 123333 );
}

BOOST_AUTO_TEST_CASE( attributeStringOperators )
{
    Catalog catalog;

    BOOST_REQUIRE_NO_THROW( catalog.Create( "a", "A7" ) );
    BOOST_REQUIRE_NO_THROW( catalog[ "a" ] );

    BOOST_REQUIRE_NO_THROW( set_attribute( "str_attr" ).of( catalog[ "a" ] ).to( std::string( "foo" ) ) );
    BOOST_REQUIRE_NO_THROW( set_attribute( "str_attr_2" ).of( catalog[ "a" ] ).to( "bar" ) );

    shared_ptr< A7 > a = catalog[ "a" ];

    // check values
    BOOST_CHECK( a -> strAtt == std::string( "foo" ) );
    BOOST_CHECK( a -> strAtt2 == std::string( "bar" ) );

    // operators
    BOOST_CHECK( ( a -> strAtt += std::string( "42" ) ) == std::string( "foo42" ) );
    BOOST_CHECK( a -> strAtt == std::string( "foo42" ) );

    BOOST_CHECK( ( a -> strAtt2 + std::string( "42" ) ) == std::string( "bar42" ) );
    BOOST_CHECK( a -> strAtt2 == std::string( "bar" ) );

    BOOST_CHECK( std::string( "42" ) + a -> strAtt2 == std::string( "42bar" ) );
    BOOST_CHECK( a -> strAtt2 == std::string( "bar" ) );

    BOOST_CHECK( a -> strAtt + a -> strAtt2 == std::string( "foo42bar" ) );
}

BOOST_AUTO_TEST_CASE( attributesKo )
{
    Catalog catalog;

    BOOST_REQUIRE_NO_THROW( catalog.Create( "a", "A7" ) );
    BOOST_REQUIRE_NO_THROW( catalog[ "a" ] );

    // bad type
    BOOST_CHECK_THROW( set_attribute( "int_attr" ).of( catalog[ "a" ] ).to( "foo" ), WrongType );
    // BOOST_CHECK_THROW( set_attribute( "ul_attr" ).of( catalog[ "a" ] ).to( -100 ), WrongType ); // ### TODO
    BOOST_CHECK_THROW( set_attribute( "bool_attr" ).of( catalog[ "a" ] ).to( 100 ), WrongType );

    // of does not exist in the catalog
    BOOST_CHECK_THROW( set_attribute( "int_attr" ).of( catalog[ "does_not_exist" ] ).to( "foo" ), ElementNotFound );
    // attribute does not exist in the part
    BOOST_CHECK_THROW( set_attribute( "does_not_exist" ).of( catalog[ "a" ] ).to( "foo" ), ElementNotFound );
    BOOST_CHECK_THROW( set_attribute( "does_not_exist" ).of( catalog[ "a" ] ).to( std::string( "foo" ) ), ElementNotFound );
    BOOST_CHECK_THROW( set_attribute( "does_not_exist" ).of( catalog[ "a" ] ).to( true ), ElementNotFound );

    wallaroo_within( catalog )
    {
        // of does not exist in the catalog
        BOOST_CHECK_THROW( set_attribute( "int_attr" ).of( "does_not_exist" ).to( "foo" ), ElementNotFound );
        // attribute does not exist in the part
        BOOST_CHECK_THROW( set_attribute( "does_not_exist" ).of( "a" ).to( "foo" ), ElementNotFound );
    }

    // no catalog selected:
    BOOST_CHECK_THROW( set_attribute( "int_attr" ).of( "a" ).to( -123 ), CatalogNotSpecified );
}

BOOST_AUTO_TEST_CASE( stringAttributes )
{
    Catalog catalog;

    BOOST_REQUIRE_NO_THROW( catalog.Create( "a", "A7" ) );
    BOOST_REQUIRE_NO_THROW( catalog[ "a" ] );

    wallaroo_within( catalog )
    {
        BOOST_REQUIRE_NO_THROW( set_attribute( "str_attr" ).of( "a" ).to( std::string( "mystring" ) ) );
        BOOST_REQUIRE_NO_THROW( set_attribute( "str_attr_2" ).of( "a" ).to( "mystring2" ) );
        BOOST_REQUIRE_NO_THROW( set_attribute( "int_attr" ).of( "a" ).to( "-123" ) );
        BOOST_REQUIRE_NO_THROW( set_attribute( "ul_attr" ).of( "a" ).to( "123456" ) );
        BOOST_REQUIRE_NO_THROW( set_attribute( "bool_attr" ).of( "a" ).to( "false" ) );
    }

    shared_ptr< A7 > a = catalog[ "a" ];
    BOOST_CHECK( a -> strAtt == std::string( "mystring" ) );
    BOOST_CHECK( a -> strAtt2 == std::string( "mystring2" ) );
    BOOST_CHECK( a -> intAtt == -123 );
    BOOST_CHECK( a -> ulAtt == 123456 );
    BOOST_CHECK( a -> boolAtt == false );
}

static void TestContent( Catalog& catalog )
{
    shared_ptr< A7 > a1 = catalog[ "a1" ];
    BOOST_CHECK( a1 -> intAtt == -123 );

    shared_ptr< A7 > a2 = catalog[ "a2" ];
    BOOST_CHECK( a2 -> boolAtt == false );
    BOOST_CHECK( a2 -> ulAtt == 123456 );

    shared_ptr< B7 > b1 = catalog[ "b1" ];
    BOOST_CHECK( b1->schAtt == 'z' );
    BOOST_CHECK( b1->uchAtt == 'x' );
    BOOST_CHECK( b1->ssiAtt == -6000 );
    BOOST_CHECK( b1->usiAtt == 6000 );
    BOOST_CHECK( b1->siAtt == -333333 );
    BOOST_CHECK( b1->uiAtt == 333333 );
    BOOST_CHECK( b1->sliAtt == -999999999 );
    BOOST_CHECK( b1->uliAtt == 999999999 );
    BOOST_CHECK( b1->fAtt == -1.0 );
    BOOST_CHECK( b1->dAtt == 2.0 );
    BOOST_CHECK( b1->ldAtt == 4.5 );
    BOOST_CHECK( b1->strAtt == std::string( "foo bar" ) );
    BOOST_CHECK( b1 -> boolAtt == false );
}

BOOST_AUTO_TEST_CASE( JsonAttributes )
{
    JsonConfiguration file( "test_attributes.json" );
    Catalog catalog;
    BOOST_REQUIRE_NO_THROW( file.Fill( catalog ) );
    TestContent( catalog );
}

BOOST_AUTO_TEST_CASE( XmlAttributes )
{
    XmlConfiguration file( "test_attributes.xml" );
    Catalog catalog;
    BOOST_REQUIRE_NO_THROW( file.Fill( catalog ) );
    TestContent( catalog );
}

BOOST_AUTO_TEST_CASE( initMethod )
{
    Catalog catalog;

    // create some objects
    BOOST_REQUIRE_NO_THROW( catalog.Create( "c1", "C7" ) );
    BOOST_REQUIRE_NO_THROW( catalog.Create( "c2", "C7" ) );
    BOOST_REQUIRE_NO_THROW( catalog.Create( "c3", "C7" ) );

    // this should call Init for every object in the catalog
    catalog.Init();

    // check every object has been initialized
    shared_ptr< C7 > c1 = catalog[ "c1" ];
    shared_ptr< C7 > c2 = catalog[ "c2" ];
    shared_ptr< C7 > c3 = catalog[ "c3" ];
    BOOST_CHECK( c1 -> ready );
    BOOST_CHECK( c2 -> ready );
    BOOST_CHECK( c3 -> ready );
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: sarvex/wallaroo

max_issues_repo_name: sarvex/wallaroo

max_forks_repo_name: sarvex/wallaroo


text:
/*
	Copyright (C) 2013-2014 by Kristina Simpson <sweet.kristas@gmail.com>

	This software is provided 'as-is', without any express or implied
	warranty. In no event will the authors be held liable for any damages
	arising from the use of this software.

	Permission is granted to anyone to use this software for any purpose,
	including commercial applications, and to alter it and redistribute it
	freely, subject to the following restrictions:

	   1. The origin of this software must not be misrepresented; you must not
	   claim that you wrote the original software. If you use this software
	   in a product, an acknowledgement in the product documentation would be
	   appreciated but is not required.

	   2. Altered source versions must be plainly marked as such, and must not be
	   misrepresented as being the original software.

	   3. This notice may not be removed or altered from any source
	   distribution.
*/

#include <boost/lexical_cast.hpp>
#include <boost/regex.hpp>

#include <algorithm>
#include <map>
#include <string>
#include "asserts.hpp"
#include "Color.hpp"

namespace KRE
{
	namespace
	{
		template<typename T>
		T clamp(T value, T minval, T maxval)
		{
			return std::min<T>(maxval, std::max(value, minval));
		}

		typedef std::map<std::string, Color> color_table_type;
		void create_color_table(color_table_type& color_table)
		{
			color_table["aliceblue"] = Color(240, 248, 255);
			color_table["antiquewhite"] = Color(250, 235, 215);
			color_table["antique_white"] = Color(250, 235, 215);
			color_table["aqua"] = Color(0, 255, 255);
			color_table["aquamarine"] = Color(127, 255, 212);
			color_table["azure"] = Color(240, 255, 255);
			color_table["beige"] = Color(245, 245, 220);
			color_table["bisque"] = Color(255, 228, 196);
			color_table["black"] = Color(0, 0, 0);
			color_table["blanchedalmond"] = Color(255, 235, 205);
			color_table["blue"] = Color(0, 0, 255);
			color_table["blueviolet"] = Color(138, 43, 226);
			color_table["brown"] = Color(165, 42, 42);
			color_table["burlywood"] = Color(222, 184, 135);
			color_table["cadetblue"] = Color(95, 158, 160);
			color_table["chartreuse"] = Color(127, 255, 0);
			color_table["chocolate"] = Color(210, 105, 30);
			color_table["coral"] = Color(255, 127, 80);
			color_table["cornflowerblue"] = Color(100, 149, 237);
			color_table["cornsilk"] = Color(255, 248, 220);
			color_table["crimson"] = Color(220, 20, 60);
			color_table["cyan"] = Color(0, 255, 255);
			color_table["darkblue"] = Color(0, 0, 139);
			color_table["darkcyan"] = Color(0, 139, 139);
			color_table["darkgoldenrod"] = Color(184, 134, 11);
			color_table["darkgray"] = Color(169, 169, 169);
			color_table["darkgreen"] = Color(0, 100, 0);
			color_table["darkgrey"] = Color(169, 169, 169);
			color_table["darkkhaki"] = Color(189, 183, 107);
			color_table["darkmagenta"] = Color(139, 0, 139);
			color_table["darkolivegreen"] = Color(85, 107, 47);
			color_table["darkorange"] = Color(255, 140, 0);
			color_table["darkorchid"] = Color(153, 50, 204);
			color_table["darkred"] = Color(139, 0, 0);
			color_table["darksalmon"] = Color(233, 150, 122);
			color_table["darkseagreen"] = Color(143, 188, 143);
			color_table["darkslateblue"] = Color(72, 61, 139);
			color_table["darkslategray"] = Color(47, 79, 79);
			color_table["darkslategrey"] = Color(47, 79, 79);
			color_table["darkturquoise"] = Color(0, 206, 209);
			color_table["darkviolet"] = Color(148, 0, 211);
			color_table["deeppink"] = Color(255, 20, 147);
			color_table["deepskyblue"] = Color(0, 191, 255);
			color_table["dimgray"] = Color(105, 105, 105);
			color_table["dimgrey"] = Color(105, 105, 105);
			color_table["dodgerblue"] = Color(30, 144, 255);
			color_table["firebrick"] = Color(178, 34, 34);
			color_table["floralwhite"] = Color(255, 250, 240);
			color_table["forestgreen"] = Color(34, 139, 34);
			color_table["fuchsia"] = Color(255, 0, 255);
			color_table["gainsboro"] = Color(220, 220, 220);
			color_table["ghostwhite"] = Color(248, 248, 255);
			color_table["gold"] = Color(255, 215, 0);
			color_table["goldenrod"] = Color(218, 165, 32);
			color_table["gray"] = Color(128, 128, 128);
			color_table["grey"] = Color(128, 128, 128);
			color_table["green"] = Color(0, 128, 0);
			color_table["greenyellow"] = Color(173, 255, 47);
			color_table["honeydew"] = Color(240, 255, 240);
			color_table["hotpink"] = Color(255, 105, 180);
			color_table["indianred"] = Color(205, 92, 92);
			color_table["indigo"] = Color(75, 0, 130);
			color_table["ivory"] = Color(255, 255, 240);
			color_table["khaki"] = Color(240, 230, 140);
			color_table["lavender"] = Color(230, 230, 250);
			color_table["lavenderblush"] = Color(255, 240, 245);
			color_table["lawngreen"] = Color(124, 252, 0);
			color_table["lemonchiffon"] = Color(255, 250, 205);
			color_table["lightblue"] = Color(173, 216, 230);
			color_table["lightcoral"] = Color(240, 128, 128);
			color_table["lightcyan"] = Color(224, 255, 255);
			color_table["lightgoldenrodyellow"] = Color(250, 250, 210);
			color_table["lightgray"] = Color(211, 211, 211);
			color_table["lightgreen"] = Color(144, 238, 144);
			color_table["lightgrey"] = Color(211, 211, 211);
			color_table["lightpink"] = Color(255, 182, 193);
			color_table["lightsalmon"] = Color(255, 160, 122);
			color_table["lightseagreen"] = Color(32, 178, 170);
			color_table["lightskyblue"] = Color(135, 206, 250);
			color_table["lightslategray"] = Color(119, 136, 153);
			color_table["lightslategrey"] = Color(119, 136, 153);
			color_table["lightsteelblue"] = Color(176, 196, 222);
			color_table["lightyellow"] = Color(255, 255, 224);
			color_table["lime"] = Color(0, 255, 0);
			color_table["limegreen"] = Color(50, 205, 50);
			color_table["linen"] = Color(250, 240, 230);
			color_table["magenta"] = Color(255, 0, 255);
			color_table["maroon"] = Color(128, 0, 0);
			color_table["mediumaquamarine"] = Color(102, 205, 170);
			color_table["mediumblue"] = Color(0, 0, 205);
			color_table["mediumorchid"] = Color(186, 85, 211);
			color_table["mediumpurple"] = Color(147, 112, 219);
			color_table["mediumseagreen"] = Color(60, 179, 113);
			color_table["mediumslateblue"] = Color(123, 104, 238);
			color_table["mediumspringgreen"] = Color(0, 250, 154);
			color_table["mediumturquoise"] = Color(72, 209, 204);
			color_table["mediumvioletred"] = Color(199, 21, 133);
			color_table["midnightblue"] = Color(25, 25, 112);
			color_table["mintcream"] = Color(245, 255, 250);
			color_table["mistyrose"] = Color(255, 228, 225);
			color_table["moccasin"] = Color(255, 228, 181);
			color_table["navajowhite"] = Color(255, 222, 173);
			color_table["navy"] = Color(0, 0, 128);
			color_table["oldlace"] = Color(253, 245, 230);
			color_table["olive"] = Color(128, 128, 0);
			color_table["olivedrab"] = Color(107, 142, 35);
			color_table["orange"] = Color(255, 165, 0);
			color_table["orangered"] = Color(255, 69, 0);
			color_table["orchid"] = Color(218, 112, 214);
			color_table["palegoldenrod"] = Color(238, 232, 170);
			color_table["palegreen"] = Color(152, 251, 152);
			color_table["paleturquoise"] = Color(175, 238, 238);
			color_table["palevioletred"] = Color(219, 112, 147);
			color_table["papayawhip"] = Color(255, 239, 213);
			color_table["peachpuff"] = Color(255, 218, 185);
			color_table["peru"] = Color(205, 133, 63);
			color_table["pink"] = Color(255, 192, 203);
			color_table["plum"] = Color(221, 160, 221);
			color_table["powderblue"] = Color(176, 224, 230);
			color_table["purple"] = Color(128, 0, 128);
			color_table["red"] = Color(255, 0, 0);
			color_table["rosybrown"] = Color(188, 143, 143);
			color_table["royalblue"] = Color(65, 105, 225);
			color_table["saddlebrown"] = Color(139, 69, 19);
			color_table["salmon"] = Color(250, 128, 114);
			color_table["sandybrown"] = Color(244, 164, 96);
			color_table["seagreen"] = Color(46, 139, 87);
			color_table["seashell"] = Color(255, 245, 238);
			color_table["sienna"] = Color(160, 82, 45);
			color_table["silver"] = Color(192, 192, 192);
			color_table["skyblue"] = Color(135, 206, 235);
			color_table["slateblue"] = Color(106, 90, 205);
			color_table["slategray"] = Color(112, 128, 144);
			color_table["slategrey"] = Color(112, 128, 144);
			color_table["snow"] = Color(255, 250, 250);
			color_table["springgreen"] = Color(0, 255, 127);
			color_table["steelblue"] = Color(70, 130, 180);
			color_table["tan"] = Color(210, 180, 140);
			color_table["teal"] = Color(0, 128, 128);
			color_table["thistle"] = Color(216, 191, 216);
			color_table["tomato"] = Color(255, 99, 71);
			color_table["turquoise"] = Color(64, 224, 208);
			color_table["violet"] = Color(238, 130, 238);
			color_table["wheat"] = Color(245, 222, 179);
			color_table["white"] = Color(255, 255, 255);
			color_table["whitesmoke"] = Color(245, 245, 245);
			color_table["yellow"] = Color(255, 255, 0);
			color_table["yellowgreen"] = Color(154, 205, 50);
		}

		color_table_type& get_color_table()
		{
			static color_table_type res;
			if(res.empty()) {
				create_color_table(res);
			}
			return res;
		}

		float convert_string_to_number(const std::string& str)
		{
			try {
				float value = boost::lexical_cast<float>(str);
				if(value > 1.0) {
					// Assume it's an integer value.
					return value / 255.0f;
				} else if(value < 1.0f) {
					return value;
				} else {
					// value = 1.0 -- check the string to try and disambiguate
					if(str == "1" || str.find('.') == std::string::npos) {
						return 1.0f / 255.0f;
					}
					return 1.0f;
				}
			} catch(boost::bad_lexical_cast&) {
				ASSERT_LOG(false, "unable to convert value to number: " << str);
			}
		}

		float convert_numeric(const variant& node, DecodingHint hint)
		{
			if(node.is_float()) {
				if(node.as_float() > 1.0 && hint == DecodingHint::INTEGER) {
					return clamp<int>(node.as_int32(), 0, 255) / 255.0f;
				}
				return clamp<float>(node.as_float(), 0.0f, 1.0f);
			} else if(node.is_int()) {
				if(node.as_float() <= 1.0f && hint == DecodingHint::DECIMAL) {
					return clamp<float>(node.as_float(), 0.0f, 1.0f);
				}
				return clamp<int>(node.as_int32(), 0, 255) / 255.0f;
			} else if(node.is_string()) {
				return convert_string_to_number(node.as_string());
			}
			ASSERT_LOG(false, "attribute of Color value was expected to be numeric type.");
			return 1.0f;
		}

		bool convert_hex_digit(char d, int* value)
		{
			if(d >= 'A' && d <= 'F') {
				*value = d - 'A' + 10;
			} else if(d >= 'a' && d <= 'f') {
				*value = d - 'a' + 10;
			} else if(d >= '0' && d <= '9') {
				*value = d - '0';
			} else {
				return false;
			}
			return true;
		}

		bool color_from_hex_string(const std::string& colstr, Color* value)
		{
			std::string s = colstr;
			if(s.empty()) {
				return false;
			}
			if(s[0] == '#') {
				s = s.substr(1);
			}
			if(s.length() != 3 && s.length() != 6 && s.length() != 8) {
				return false;
			}
			if(s.length() == 3) {
				int r_hex = 0, g_hex = 0, b_hex = 0;
				if(convert_hex_digit(s[0], &r_hex) && convert_hex_digit(s[1], &g_hex) && convert_hex_digit(s[2], &b_hex)) {
					*value = Color((r_hex << 4) | r_hex, (g_hex << 4) | g_hex, (b_hex << 4) | b_hex);
					return true;
				}
				return false;
			}
			int rh_hex = 0, rl_hex = 0, gh_hex = 0, gl_hex = 0, bh_hex = 0, bl_hex = 0;
			if(convert_hex_digit(s[0], &rh_hex) && convert_hex_digit(s[1], &rl_hex)
				&& convert_hex_digit(s[2], &gh_hex) && convert_hex_digit(s[3], &gl_hex)
				&& convert_hex_digit(s[4], &bh_hex) && convert_hex_digit(s[5], &bl_hex)) {
					int ah_hex = 0xf, al_hex = 0xf;
					if(s.length() == 8) {
						if(!convert_hex_digit(s[6], &ah_hex) || !convert_hex_digit(s[7], &al_hex)) {
							return false;
						}
					}
					*value = Color((rh_hex << 4) | rl_hex, (gh_hex << 4) | gl_hex, (bh_hex << 4) | bl_hex, (ah_hex << 4) | al_hex);
					return true;
			}
			return false;
		}

		std::vector<std::string> split(const std::string& input, const std::string& re) {
			// passing -1 as the submatch index parameter performs splitting
			boost::regex regex(re);
			boost::sregex_token_iterator first(input.begin(), input.end(), regex, -1), last;
			return std::vector<std::string>(first, last);
		}

		bool color_from_hsv_string(const std::string& colstr, Color* color)
		{
			if(colstr.empty()) {
				return false;
			}
			if(colstr.size() > 5 && colstr.substr(0,4) == "hsv(") {
				float hsv_col[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
				auto buf = split(colstr, ",| |;");
				unsigned n = 0;
				for(auto& s : buf) {
					hsv_col[n] = convert_string_to_number(s);
					if(++n >= 4) {
						break;
					}
				}
				*color = Color::from_hsv(hsv_col[0], hsv_col[1], hsv_col[2], hsv_col[3]);
				return true;
			}
			return false;
		}

		struct rgb
		{
			uint8_t r, g, b;
		};

		struct hsv
		{
			uint8_t h, s, v;
		};

		hsv rgb_to_hsv(uint8_t r, uint8_t g, uint8_t b)
		{
			hsv out;
			uint8_t min_color, max_color, delta;

			min_color = std::min(r, std::min(g, b));
			max_color = std::max(r, std::max(g, b));

			delta = max_color - min_color;
			out.v = max_color;
			if(out.v == 0) {
				out.s = 0;
				out.h = 0;
				return out;
			}

			out.s = static_cast<uint8_t>(255.0f * delta / out.v);
			if(out.s == 0) {
				out.h = 0;
				return out;
			}

			if(r == max_color) {
				out.h = static_cast<uint8_t>(43.0f * (g-b)/delta);
			} else if(g == max_color) {
				out.h = 85 + static_cast<uint8_t>(43.0f * (b-r)/delta);
			} else {
				out.h = 171 + static_cast<uint8_t>(43.0f * (r-g)/delta);
			}
			return out;
		}

		rgb hsv_to_rgb(uint8_t h, uint8_t s, uint8_t v)
		{
			rgb out;

			if(s == 0) {
				out.r = out.g = out.b = v;
			} else {
				const uint8_t region = h / 43;
				const uint8_t remainder = (h - (region * 43)) * 6;

				const uint8_t p = (v * (255 - s)) >> 8;
				const uint8_t q = (v * (255 - ((s * remainder) >> 8))) >> 8;
				const uint8_t t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8;

				switch(region)
				{
					case 0:  out.r = v; out.g = t; out.b = p; break;
					case 1:  out.r = q; out.g = v; out.b = p; break;
					case 2:  out.r = p; out.g = v; out.b = t; break;
					case 3:  out.r = p; out.g = q; out.b = v; break;
					case 4:  out.r = t; out.g = p; out.b = v; break;
					default: out.r = v; out.g = p; out.b = q; break;
				}
			}
			return out;
		}

		void hsv_to_rgb(const float h, const float s, const float v, float* const out)
		{
			if(std::abs(s) < FLT_EPSILON) {
				out[0] = out[1] = out[2] = v;
			} else {
				const float h_dash = h * 360.0f;
				// n.b. we assume h is scaled 0-1 rather than 0-360, hence the scaling factor is 6 rather than 60
				const float region = h_dash / 60.0f;
				const int int_region = static_cast<int>(std::floor(region)) % 6;
				const float remainder = region - std::floor(region);

				const float p = v * (1.0f - s);
				const float q = v * (1.0f - s * remainder);
				const float t = v * (1.0f - s * (1.0f - remainder));

				switch(int_region)
				{
					case 0:  out[0] = v; out[1] = t; out[2] = p; break;
					case 1:  out[0] = q; out[1] = v; out[2] = p; break;
					case 2:  out[0] = p; out[1] = v; out[2] = t; break;
					case 3:  out[0] = p; out[1] = q; out[2] = v; break;
					case 4:  out[0] = t; out[1] = p; out[2] = v; break;
					default: out[0] = v; out[1] = p; out[2] = q; break;
				}
			}
		}

		void rgb_to_hsv(const float* const rgbf, float* const out)
		{
			const float min_color = std::min(rgbf[0], std::min(rgbf[1], rgbf[2]));
			const float max_color = std::max(rgbf[0], std::max(rgbf[1], rgbf[2]));
			const float delta = max_color - min_color;

			out[2] = max_color;
			if(std::abs(out[2]) < FLT_EPSILON) {
				out[1] = 0;
				out[0] = 0;
				return;
			}

			out[1] = delta / out[2];
			if(std::abs(out[1]) < FLT_EPSILON) {
				out[0] = 0;
				return;
			}

			if(rgbf[0] == max_color) {
				out[0] = (43.0f * (rgbf[1]-rgbf[2])/delta);
			} else if(rgbf[1] == max_color) {
				out[0] = (85.0f/255.0f) + ((43.0f/255.0f) * (rgbf[2]-rgbf[0])/delta);
			} else {
				out[0] = (171.0f/255.0f) + ((43.0f/255.0f) * (rgbf[0]-rgbf[1])/delta);
			}
		}

		bool color_from_basic_string(const std::string& colstr, Color* color)
		{
			float value[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
			auto buf = split(colstr, ",| |;");
			if(buf.size() == 0) {
				return false;
			}
			unsigned n = 0;
			for(auto& s : buf) {
				value[n] = convert_string_to_number(s);
				if(++n >= 4) {
					break;
				}
			}
			*color = Color(value[0], value[1], value[2], value[3]);
			return true;
		}

		bool color_from_string(const std::string& colstr, Color* color)
		{
			ASSERT_LOG(!colstr.empty(), "Empty string passed to Color constructor.");
			auto it = get_color_table().find(colstr);
			if(it == get_color_table().end()) {
				if(!color_from_hsv_string(colstr, color)) {
					if(!color_from_hex_string(colstr, color)) {
						if(!color_from_basic_string(colstr, color)) {
							ASSERT_LOG(false, "Couldn't parse color '" << colstr << "' from string value.");
						}
					}
				}
			} else {
				*color = it->second;
			}
			return true;
		}
	}

	Color::Color()
		: icolor_(255),
		  color_(1.0f)
	{
	}

	Color::~Color()
	{
	}

	Color::Color(const float r, const float g, const float b, const float a)
		: color_(r, g, b, a)
	{
		convert_to_icolor();
	}

	Color::Color(const int r, const int g, const int b, const int a)
		: icolor_(clamp(r,0,255), clamp(g,0,255), clamp(b,0,255), clamp(a,0,255))
	{
		convert_to_color();
	}

	Color::Color(const glm::vec4& value)
		: color_(value)
	{
		convert_to_icolor();
	}

	Color::Color(const glm::u8vec4& value)
		: icolor_(value)
	{
		convert_to_color();
	}

	Color::Color(const variant& node, DecodingHint hint)
		: icolor_(255, 255, 255, 255),
		  color_(1.0f, 1.0f, 1.0f, 1.0f)
	{
		if(node.is_string()) {
			color_from_string(node.as_string(), this);
		} else if(node.is_list()) {
			ASSERT_LOG(node.num_elements() == 3 || node.num_elements() == 4,
				"Color nodes must be lists of 3 or 4 numbers.");
			for(size_t n = 0; n != node.num_elements(); ++n) {
				color_[n] = convert_numeric(node[n], hint);
				icolor_[n] = static_cast<int>(color_[n] * 255.0f);
			}
		} else if(node.is_map()) {
			if(node.has_key("red")) {
				color_[0] = convert_numeric(node["red"], hint);
				icolor_[0] = static_cast<int>(color_[0] * 255.0f);
			} else if(node.has_key("r")) {
				color_[0] = convert_numeric(node["r"], hint);
				icolor_[0] = static_cast<int>(color_[0] * 255.0f);
			}
			if(node.has_key("green")) {
				color_[1] = convert_numeric(node["green"], hint);
				icolor_[1] = static_cast<int>(color_[1] * 255.0f);
			} else if(node.has_key("g")) {
				color_[1] = convert_numeric(node["g"], hint);
				icolor_[1] = static_cast<int>(color_[1] * 255.0f);
			}
			if(node.has_key("blue")) {
				color_[2] = convert_numeric(node["blue"], hint);
				icolor_[2] = static_cast<int>(color_[2] * 255.0f);
			} else if(node.has_key("b")) {
				color_[2] = convert_numeric(node["b"], hint);
				icolor_[2] = static_cast<int>(color_[2] * 255.0f);
			}
			if(node.has_key("alpha")) {
				color_[3] = convert_numeric(node["alpha"], hint);
				icolor_[3] = static_cast<int>(color_[3] * 255.0f);
			} else if(node.has_key("a")) {
				color_[3] = convert_numeric(node["a"], hint);
				icolor_[3] = static_cast<int>(color_[3] * 255.0f);
			}
		} else {
			ASSERT_LOG(false, "Unrecognised Color value: " << node.to_debug_string());
		}
	}

	Color::Color(unsigned long n, ColorByteOrder order)
	{
		int ib0 = (n & 0xff);
		int ib1 = ((n >> 8) & 0xff);
		int ib2 = ((n >> 16) & 0xff);
		int ib3 = ((n >> 24) & 0xff);
		switch(order)
		{
			case ColorByteOrder::RGBA:
				icolor_ = glm::u8vec4(ib3, ib2, ib1, ib0);
				break;
			case ColorByteOrder::ARGB:
				icolor_ = glm::u8vec4(ib2, ib1, ib0, ib3);
				break;
			case ColorByteOrder::BGRA:
				icolor_ = glm::u8vec4(ib1, ib2, ib3, ib0);
				break;
			case ColorByteOrder::ABGR:
				icolor_ = glm::u8vec4(ib0, ib1, ib2, ib3);
				break;
			default:
				ASSERT_LOG(false, "Unknown ColorByteOrder value: " << static_cast<int>(order));
				break;
		}
		convert_to_color();
	}

	Color::Color(const std::string& colstr)
	{
		ASSERT_LOG(!colstr.empty(), "Empty string passed to Color constructor.");
		color_from_string(colstr, this);
	}

	void Color::setAlpha(int a)
	{
		icolor_.a = a;
		color_[3] = clamp<int>(a, 0, 255) / 255.0f;
	}

	void Color::setAlpha(float a)
	{
		color_.a = clamp<float>(a, 0.0f, 1.0f);
		icolor_.a = static_cast<int>(color_.a * 255.0f);
	}

	void Color::setRed(int r)
	{
		icolor_.r = r;
		color_.r = clamp<int>(r, 0, 255) / 255.0f;
	}

	void Color::setRed(float r)
	{
		color_.r = clamp<float>(r, 0.0f, 1.0f);
		icolor_.r = static_cast<int>(color_.r * 255.0f);
	}

	void Color::setGreen(int g)
	{
		icolor_.g = g;
		color_.g = clamp<int>(g, 0, 255) / 255.0f;
	}

	void Color::setGreen(float g)
	{
		color_.g = clamp<float>(g, 0.0f, 1.0f);
		icolor_.g = static_cast<int>(color_.g * 255.0f);
	}

	void Color::setBlue(int b)
	{
		icolor_.b = b;
		color_.b = clamp<int>(b, 0, 255) / 255.0f;
	}

	void Color::setBlue(float b)
	{
		color_.b = clamp<float>(b, 0.0f, 1.0f);
		icolor_.b = static_cast<int>(color_.b * 255.0f);
	}

	ColorPtr Color::factory(const std::string& name)
	{
		auto it = get_color_table().find(name);
		ASSERT_LOG(it != get_color_table().end(), "Couldn't find color '" << name << "' in known color list");
		return ColorPtr(new Color(it->second));
	}

	variant Color::write() const
	{
		// XXX we should store information on how the Color value was given to us, if it was
		// a variant, then output in same format.
		std::vector<variant> v;
		v.reserve(4);
		v.push_back(variant(r()));
		v.push_back(variant(g()));
		v.push_back(variant(b()));
		v.push_back(variant(a()));
		return variant(&v);
	}

	Color operator*(const Color& lhs, const Color& rhs)
	{
		return Color(lhs.r()*rhs.r(), lhs.g()*rhs.g(), lhs.b()*rhs.b(), lhs.a()*rhs.a());
	}

	void Color::preMultiply(int alpha)
	{
		// ignore current alpha and multiply all the colors by the given alpha, setting the new alpha to fully opaque
		const float a = static_cast<float>(clamp<int>(alpha, 0, 255) / 255.0f);
		color_[0] *= a;
		color_[1] *= a;
		color_[2] *= a;
		color_[3] = 1.0f;
		convert_to_icolor();
	}

	void Color::preMultiply(float alpha)
	{
		// ignore current alpha and multiply all the colors by the given alpha, setting the new alpha to fully opaque
		const float a = clamp<float>(alpha, 0.0f, 1.0f);
		color_[0] *= a;
		color_[1] *= a;
		color_[2] *= a;
		color_[3] = 1.0f;
		convert_to_icolor();
	}

	void Color::preMultiply()
	{
		color_[0] *= color_[3];
		color_[1] *= color_[3];
		color_[2] *= color_[3];
		color_[3] = 1.0f;
	}

	glm::u8vec4 Color::to_hsv() const
	{
		hsv outp = rgb_to_hsv(ri(), gi(), bi());
		return glm::u8vec4(outp.h, outp.s, outp.v, ai());
	}

	glm::vec4 Color::to_hsv_vec4() const
	{
		glm::vec4 vec;
		rgb_to_hsv(glm::value_ptr(color_), glm::value_ptr(vec));
		return vec;
	}

	Color Color::from_hsv(int h, int s, int v, int a)
	{
		rgb outp = hsv_to_rgb(h, s, v);
		return Color(outp.r, outp.g, outp.b, a);
	}

	Color Color::from_hsv(float h, float s, float v, float a)
	{
		glm::vec4 outp;
		outp.a = a;
		hsv_to_rgb(h, s, v, glm::value_ptr(outp));
		return Color(outp);
	}

	void Color::convert_to_icolor()
	{
		icolor_.r = clamp(static_cast<int>(color_.r * 255.0f), 0, 255);
		icolor_.g = clamp(static_cast<int>(color_.g * 255.0f), 0, 255);
		icolor_.b = clamp(static_cast<int>(color_.b * 255.0f), 0, 255);
		icolor_.a = clamp(static_cast<int>(color_.a * 255.0f), 0, 255);
	}

	void Color::convert_to_color()
	{
		color_.r = clamp(icolor_.r / 255.0f, 0.0f, 1.0f);
		color_.g = clamp(icolor_.g / 255.0f, 0.0f, 1.0f);
		color_.b = clamp(icolor_.b / 255.0f, 0.0f, 1.0f);
		color_.a = clamp(icolor_.a / 255.0f, 0.0f, 1.0f);
	}

	std::ostream& operator<<(std::ostream& os, const Color& c)
	{
		if(c.ai() == 255) {
			os << "rgb(" << c.ri() << "," << c.gi() << "," << c.bi() << ")";
		} else {
			os << "rgba(" << c.ri() << "," << c.gi() << "," << c.bi() << "," << c.ai() << ")";
		}
		return os;
	}
}

max_stars_repo_name: gamobink/anura

max_issues_repo_name: gamobink/anura

max_forks_repo_name: gamobink/anura


text:
/*
 * Copyright 2019, Offchain Labs, Inc.
 *
 * 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.
 */

#include "config.hpp"

#include <avm_values/tuple.hpp>
#include <avm_values/value.hpp>

#include <catch2/catch.hpp>
#include <nlohmann/json.hpp>

#include <boost/algorithm/hex.hpp>

#include <fstream>
#include <iostream>

std::vector<char> hexStringToBytes(const std::string& hexstr) {
    std::vector<char> bytes;
    bytes.reserve(hexstr.size() / 2);
    boost::algorithm::unhex(hexstr.begin(), hexstr.end(), bytes.begin());
    return bytes;
}

TEST_CASE("Value hashing") {
    std::ifstream i(test_cases_path);
    nlohmann::json j;
    i >> j;
    for (auto valtest : j) {
        // Don't include codepoints in test
        if (valtest["is_codepoint"]) {
            continue;
        }
        DYNAMIC_SECTION("Test " << valtest["name"].get<std::string>()) {
            auto valBytes =
                hexStringToBytes(valtest["value"].get<std::string>());
            auto valRaw = reinterpret_cast<const char*>(valBytes.data());
            uint256_t givenHash = intx::from_string<uint256_t>(
                std::string("0x") + valtest["hash"].get<std::string>());
            auto val = deserialize_value(valRaw);
            auto calcHash = hash_value(val);
            REQUIRE(givenHash == calcHash);
        }
    }
}

// Test is disabled since it it incompatible with the new codepoint system
TEST_CASE("Value marshaling") {
    std::ifstream i(test_cases_path);
    nlohmann::json j;
    i >> j;
    for (auto valtest : j) {
        // Don't include codepoints in test
        if (valtest["is_codepoint"]) {
            continue;
        }
        DYNAMIC_SECTION("Test " << valtest["name"].get<std::string>()) {
            auto valBytes =
                hexStringToBytes(valtest["value"].get<std::string>());
            auto valRaw = reinterpret_cast<const char*>(valBytes.data());
            auto val = deserialize_value(valRaw);
            std::vector<unsigned char> buf;
            marshal_value(val, buf);
            auto valptr = (const char*)&buf[0];
            auto newval = deserialize_value(valptr);
            auto valsEqual = val == newval;
            REQUIRE(valsEqual);
            // REQUIRE(val == newval); junit output broken with map::at error
        }
    }
}

max_issues_repo_name: dionyziz/arbitrum

max_forks_repo_name: dionyziz/arbitrum


text:
#include "shift/network/udp_socket.hpp"
#include "shift/network/udp_socket_impl.hpp"
#include "shift/network/network_host.hpp"
#include <shift/log/log.hpp>
#include <shift/core/boost_disable_warnings.hpp>
#include <boost/array.hpp>
#include <boost/bind.hpp>
#include <boost/asio/ip/multicast.hpp>
#include <shift/core/boost_restore_warnings.hpp>
#include <functional>

namespace shift::network
{
udp_socket::udp_socket() : _impl(std::make_unique<impl>())
{
}

udp_socket::~udp_socket()
{
  // If the following assertion fails you did a bad job in making sure that
  // all socket instances are being destroyed before the network host.
  BOOST_ASSERT(network_host::singleton_instantiated());

  if (_impl->underlying_socket.is_open())
  {
    /// ToDo: Calling close from dtor doesn't work as it attempts to call
    /// this->shared_from_this(), which is no longer valid here.
    close();
  }
  if (_impl->host.debug_socket_lifetime)
    network_log() << "Deleting Udp socket.";
}

bool udp_socket::open(const boost::asio::ip::address& bind_address,
                      std::uint16_t bind_port,
                      const boost::asio::ip::address& multicast_address)
{
  return _impl->open(*this, bind_address, bind_port, multicast_address);
}

void udp_socket::close()
{
  _impl->close(*this);
}

void udp_socket::post(std::vector<char> buffer,
                      const boost::asio::ip::udp::endpoint& destination)
{
  // Serialize posting of new buffers with udp_socket::writeRoutine.
  _impl->read_write_strand.post(boost::bind(&udp_socket::impl::post,
                                            _impl.get(), shared_from_this(),
                                            std::move(buffer), destination));
}

void udp_socket::queue(std::vector<char> buffer,
                       const boost::asio::ip::udp::endpoint& sender)
{
  network_host::singleton_instance().queue_datagram(shared_from_this(),
                                                    std::move(buffer), sender);
}

boost::asio::ip::udp::endpoint udp_socket::local_endpoint() const
{
  return _impl->local_endpoint;
}
}

max_stars_repo_name: cspanier/shift

max_issues_repo_name: cspanier/shift

max_forks_repo_name: cspanier/shift


text:
/**
 *    Copyright (C) 2012 10gen Inc.
 *
 *    This program is free software: you can redistribute it and/or  modify
 *    it under the terms of the GNU Affero General Public License, version 3,
 *    as published by the Free Software Foundation.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <boost/scoped_ptr.hpp>
#include <string>
#include <vector>

#include "mongo/db/jsobj.h"
#include "mongo/dbtests/mock/mock_conn_registry.h"
#include "mongo/dbtests/mock/mock_remote_db_server.h"
#include "mongo/s/collection_manager.h"
#include "mongo/s/metadata_loader.h"
#include "mongo/s/type_chunk.h"
#include "mongo/s/type_collection.h"
#include "mongo/s/util.h" // for ShardChunkVersion
#include "mongo/unittest/unittest.h"
#include "mongo/util/net/hostandport.h"

namespace {

    using boost::scoped_ptr;
    using mongo::BSONObj;
    using mongo::BSONArray;
    using mongo::ChunkType;
    using mongo::ConnectionString;
    using mongo::CollectionManager;
    using mongo::CollectionType;
    using mongo::Date_t;
    using mongo::HostAndPort;
    using mongo::MAXKEY;
    using mongo::MetadataLoader;
    using mongo::MINKEY;
    using mongo::OID;
    using mongo::ShardChunkVersion;
    using mongo::MockConnRegistry;
    using mongo::MockRemoteDBServer;
    using std::string;
    using std::vector;

    // XXX
    // We'd move all the cloning tests here.
    //
    // The "make()" tests belong into the config_reader_test

    class SingleChunkFixture : public mongo::unittest::Test {
    protected:
        scoped_ptr<CollectionManager> manager;
        scoped_ptr<MockRemoteDBServer> dummyConfig;

        void setUp() {
            dummyConfig.reset(new MockRemoteDBServer("$dummy_config"));
            mongo::ConnectionString::setConnectionHook(MockConnRegistry::get()->getConnStrHook());
            MockConnRegistry::get()->addServer(dummyConfig.get());

            BSONObj collFoo =  BSON(CollectionType::ns("test.foo") <<
                                    CollectionType::keyPattern(BSON("a" << 1)) <<
                                    CollectionType::unique(false) <<
                                    CollectionType::updatedAt(1ULL) <<
                                    CollectionType::epoch(OID::gen()));
            // XXX Awaiting mock review
            //dummyConfig.setQueryReply("config.collections", BSONArray(collFoo));

            BSONObj fooSingle = BSON(ChunkType::name("test.foo-a_MinKey") <<
                                     ChunkType::ns("test.foo") <<
                                     ChunkType::min(BSON("a" << 10)) <<
                                     ChunkType::max(BSON("a" << 20)) <<
                                     ChunkType::DEPRECATED_lastmod(Date_t(1)) <<
                                     ChunkType::shard("shard0000"));
            // XXX Awaiting mock review
            //dummyConfig.setQueryReply("config.chunks", BSONArray(fooSingle));

            ConnectionString configLoc(HostAndPort("$dummy_config"));
            MetadataLoader loader(configLoc);
            //manager.reset(loader.makeCollectionManager("shard0000", "test.foo", NULL, NULL));
        }

        void tearDown() {
            MockConnRegistry::get()->removeServer(dummyConfig->getServerAddress());
        }
    };

    TEST_F(SingleChunkFixture, CloneSplit) {
        // Determine split point.
        ChunkType chunk;
        chunk.setMin(BSON("a" << 10));
        chunk.setMax(BSON("a" << 20));
        vector<BSONObj> splitKeys;
        splitKeys.push_back(BSON("a" << 15));

        // Setup version to use on splitting.
        //ShardChunkVersion nextVersion = manager->getMaxShardVersion();
        //nextVersion.incMinor();

        //string errMsg;
        //CollectionManager* cloned = manager->cloneSplit(chunk, splitKeys, nextVersion, &errMsg);
        //ASSERT_TRUE(cloned != NULL);
    }

} // unnamed namespace