text:
#include "Memoization.hpp"
#include <cmath>
#include <complex>
#include <cstdlib>
#include <ctime>
#include <iostream>

#include <boost/timer/timer.hpp> // timers
#include "boost/iostreams/stream.hpp"
#include "boost/iostreams/device/null.hpp"

typedef std::complex<double> cdT;
using boost::timer::cpu_timer;
using boost::timer::cpu_times;
using boost::timer::nanosecond_type;
/*! compile with icpc/clang/g++ -std=c++14 test_Memoization.cpp -I/home/stobbe/software/include/boost -L/home/stobbe/software/lib -lboost_timer -lboost_system
 */

inline cdT iexp(double a, double phi){
	return std::exp(a + std::complex<double>(0.0,phi));
}

void test_perf(){
	// setting up primitive container as comparison
	int N = 2000;
	cdT **test_arr = new cdT*[N];
	for(int i = 0; i < N; ++i) {
    	test_arr[i] = new cdT[N];
	}
	boost::iostreams::stream< boost::iostreams::null_sink > nullStream( ( boost::iostreams::null_sink() ) );

	// setting up timer
	nanosecond_type last(0);
	cpu_timer timer;

	// setting up memoize
	auto memo_iexp = Memoize::memoize( iexp );

	for(int a = 0; a < N; a++){
		for(int phi_i = 0; phi_i < N; phi_i++ ){
			double phi = phi_i*2*3.14159265/N;
			test_arr[a][phi_i] = iexp(a,phi);

		}
	}

  	cpu_times elapsed_times(timer.elapsed());
  	nanosecond_type elapsed(elapsed_times.system + elapsed_times.user);
	std::cout << "naive array initialized, time:\t" << timer.format(5) << std::endl;
	timer.start();
	for(int a = 0; a < N; a++){
		for(int phi_i = 0; phi_i < N; phi_i++ ){
			double phi = phi_i*2*3.14159265/N;
			memo_iexp(a,phi);

		}
	}
	std::cout << "memoized initialized, time:\t" << timer.format(5) << std::endl;
	std::srand(std::time(0));
	timer.start();

	for(int phi_i = 0; phi_i < N; phi_i++ ){
		for(int a = 0; a < N; a++){
			auto a_r = std::rand()%N;
			auto phi_r = std::rand()%N;
			double phi = phi_r*2*3.14159265/N;
			nullStream << test_arr[a_r][phi_r] << phi;

		}
	}
	std::cout << "naive array read, time:\t" << timer.format(5) << std::endl;
	timer.start();

	for(int phi_i = 0; phi_i < N; phi_i++ ){
		for(int a = 0; a < N; a++){
			auto a_r = std::rand()%N;
			auto phi_r = std::rand()%N;
			double phi = phi_r*2*3.14159265/N;
			nullStream << memo_iexp(a_r,phi) << phi;

		}
	}
	std::cout << "memoized read, time:\t" << timer.format(5) << std::endl;

	for(int i = 0; i < N; ++i) {
    	delete [] test_arr[i];
	}
	delete [] test_arr;
}

int main(void)
{
	test_perf();
    return 0;
}

ext: cpp

max_stars_repo_name: Atomtomate/Memoizer

max_issues_repo_name: Atomtomate/Memoizer

max_forks_repo_name: Atomtomate/Memoizer


text:
#include <contract_engine/native_contract.hpp>
#include <policy/policy.h>
#include <base58.h>
#include <script/standard.h>
#include <memory>
#include <cstdio>
#include <boost/lexical_cast.hpp>

namespace blockchain {
    namespace contract {
#define THROW_CONTRACT_ERROR(...) FJSON_ASSERT(false, __VA_ARGS__)

        bool native_contract_finder::has_native_contract_with_key(const std::string& key)
        {
			std::vector<std::string> native_contract_keys = {
					dgp_native_contract::native_contract_key()
            };
            return std::find(native_contract_keys.begin(), native_contract_keys.end(), key) != native_contract_keys.end();
        }
        std::shared_ptr<abstract_native_contract> native_contract_finder::create_native_contract_by_key(
			blockchain::contract::PendingState* pending_state, const std::string& key, const std::string& contract_address, const native_contract_sender& sender)
        {
            if (key == dgp_native_contract::native_contract_key()) {
				return std::make_shared<dgp_native_contract>(pending_state, contract_address, sender);
			}
            else
            {
                return nullptr;
            }
            return nullptr;
        }

        void abstract_native_contract::set_contract_storage(const std::string& contract_address, const std::string& storage_name, const JsonValue& value)
        {

            if (_contract_storage_changes.find(contract_address) == _contract_storage_changes.end())
            {
				_contract_storage_changes[contract_address] = std::map<std::string, StorageDataChangeType>();
            }
            auto& storage_changes = _contract_storage_changes[contract_address];
            if (storage_changes.find(storage_name) == storage_changes.end())
            {
                StorageDataChangeType change;
                change.after = value;
				const auto &before = _pending_state->storage_service->get_contract_storage(contract_address, storage_name);
                jsondiff::JsonDiff differ;
				const auto& before_json_str = jsondiff::json_dumps(before);
				const auto& after_json_str = jsondiff::json_dumps(change.after);
				auto diff = differ.diff(before, change.after);
                change.storage_diff = diff->value();
				change.before = before;
                storage_changes[storage_name] = change;
            }
            else
            {
                auto& change = storage_changes[storage_name];
                auto before = change.before;
                auto after = value;
                change.after = after;
                jsondiff::JsonDiff differ;
				const auto& before_json_str = json_dumps(before);
                auto after_json_str = jsondiff::json_dumps(after);
				auto diff = differ.diff(before, after);
                change.storage_diff = diff->value();
            }
        }
		JsonValue abstract_native_contract::get_contract_storage(const std::string& contract_address, const std::string& storage_name)
        {
            if (_contract_storage_changes.find(contract_address) == _contract_storage_changes.end())
            {
                return _pending_state->storage_service->get_contract_storage(contract_address, storage_name);
            }
            auto& storage_changes = _contract_storage_changes[contract_address];
            if (storage_changes.find(storage_name) == storage_changes.end())
            {
                return _pending_state->storage_service->get_contract_storage(contract_address, storage_name);
            }
            return storage_changes[storage_name].after;
        }

        void abstract_native_contract::emit_event(const std::string& contract_address, const std::string& event_name, const std::string& event_arg)
        {
            FJSON_ASSERT(!event_name.empty());
			::contract::storage::ContractEventInfo info;
            info.contract_id = contract_address;
            info.event_name = event_name;
            info.event_arg = event_arg;
            _contract_exec_result.events.push_back(info);
        }

		void abstract_native_contract::merge_storage_changes_to_exec_result()
		{
			for (const auto& p : _contract_storage_changes) {
				const auto& contract_id = p.first;
				if (p.second.empty()) {
					continue;
				}
				JsonObject diff_json;
				for (const auto& p2 : p.second) {
					const auto& key = p2.first;
					const auto& change = p2.second;
					diff_json[key] = change.storage_diff;
				}
				_contract_exec_result.contract_storage_changes.push_back(std::make_pair(contract_id, std::make_shared<DiffResult>(diff_json)));
			}
		}

		void abstract_native_contract::set_error(int32_t error_code, const std::string& error_msg)
		{
			_contract_exec_result.exit_code = error_code;
			_contract_exec_result.error_message = error_msg;
		}

        bool abstract_native_contract::has_api(const std::string& api_name)
        {
            const auto& api_names = apis();
            return api_names.find(api_name) != api_names.end();
        }

		// dgp native contract
		std::string dgp_native_contract::contract_key() const
		{
			return dgp_native_contract::native_contract_key();
		}
		std::string dgp_native_contract::contract_address() const {
			return contract_id;
		}
		std::set<std::string> dgp_native_contract::apis() const {
			return { "init", "create_change_admin_proposal", "cancel_change_admin_proposal", "vote_admin", "admins",
				"current_change_admin_proposal", "current_change_params_proposal",
				"vote_change_param", "min_gas_price", "set_min_gas_price", "block_gas_limit", "set_block_gas_limit",
				"min_gas_count", "set_min_gas_count", "max_contract_bytecode_store_fee_gas_count", "set_max_contract_bytecode_store_fee_gas_count",
				"on_destroy", "on_upgrade", "on_deposit" };
		}
		std::set<std::string> dgp_native_contract::offline_apis() const {
			return {"admins", "current_change_admin_proposal", "current_change_params_proposal",
				"min_gas_price", "block_gas_limit", "min_gas_count", "max_contract_bytecode_store_fee_gas_count"};
		}
		std::set<std::string> dgp_native_contract::events() const {
			return {};
		}

		std::string dgp_native_contract::init_api(const std::string& api_name, const std::string& api_arg) {
			jsondiff::JsonArray admins;
			admins.push_back(sender.caller_address);
			set_contract_storage(contract_id, "admins", admins);
			jsondiff::JsonObject dgp_params;
			dgp_params["min_gas_price"] = DEFAULT_MIN_GAS_PRICE;
			dgp_params["block_gas_limit"] = DEFAULT_BLOCK_GAS_LIMIT;
			dgp_params["min_gas_count"] = DEFAULT_MIN_GAS_COUNT;
			dgp_params["max_contract_bytecode_store_fee_gas_count"] = MAX_CONTRACT_BYTECODE_STORE_FEE_GAS;
			set_contract_storage(contract_id, "dgp_params", dgp_params);
			set_contract_storage(contract_id, "current_change_admin_proposal", jsondiff::JsonValue());
			set_contract_storage(contract_id, "current_change_params_proposal", jsondiff::JsonValue());
			return "";
		}

		std::string dgp_native_contract::admins_api(const std::string& api_name, const std::string& api_arg) {
			const auto& admins = get_contract_storage(contract_id, "admins");
			return jsondiff::json_dumps(admins);
		}

		bool dgp_native_contract::is_address_in_admins(const jsondiff::JsonArray& admins, const std::string& addr) const
		{
			for (size_t i = 0; i < admins.size(); i++) {
				if (addr == admins[i].as_string()) {
					return true;
				}
			}
			return false;
		}

		std::string dgp_native_contract::create_change_admin_proposal_api(const std::string& api_name, const std::string& api_arg) {
			// only admin can call this api
			// api_arg: {address: string, add: bool, needAgreeCount: int}
			const auto& admins = get_contract_storage(contract_id, "admins").as<jsondiff::JsonArray>();
			if (!is_address_in_admins(admins, sender.caller_address)) {
				set_error(1, "only admin can call this api");
				return "";
			}
			const auto& current_change_admin_proposal = get_contract_storage(contract_id, "current_change_admin_proposal");
			if (!current_change_admin_proposal.is_null()) {
				set_error(1, "can't create new change-admin-proposal when a proposal already exists");
				return "";
			}
			std::string addr;
			bool add = false;
			uint64_t needAgreeCount = 1;
			try {
				const auto& arg_json = jsondiff::json_loads(api_arg);
				if (!arg_json.is_object())
					throw ::contract::storage::ContractStorageException("arg format error");
				const auto& arg_obj = arg_json.as<jsondiff::JsonObject>();
				if(arg_obj.find("address") == arg_obj.end() || !arg_obj["address"].is_string())
					throw ::contract::storage::ContractStorageException("arg format error");
				addr = arg_obj["address"].as_string();
				if (arg_obj.find("add") == arg_obj.end() || !arg_obj["add"].is_bool())
					throw ::contract::storage::ContractStorageException("arg format error");
				add = arg_obj["add"].as_bool();
				if (arg_obj.find("needAgreeCount") == arg_obj.end() || !arg_obj["needAgreeCount"].is_uint64())
					throw ::contract::storage::ContractStorageException("arg format error");
				needAgreeCount = arg_obj["needAgreeCount"].as_uint64();
			}
			catch (const std::exception& e) {
				set_error(1, "argument format error, need format: {address: string, add: bool, needAgreeCount: int}");
				return "";
			}
			if (add && is_address_in_admins(admins, addr)) {
				set_error(1, "this address is already admin, can't add again");
				return "";
			}
			if (!add && !is_address_in_admins(admins, addr)) {
				set_error(1, "this address is not admin, can't remove it");
				return "";
			}
			if (!add && admins.size() < 2) {
				set_error(1, "Can't remove admin if there is only one admin");
				return "";
			}
			CTxDestination addrDest = DecodeDestination(addr);
			if (!IsValidDestination(addrDest)) {
				set_error(1, "argument address format error");
				return "";
			}
			if (needAgreeCount<1 || needAgreeCount > admins.size())
			{
				set_error(1, "argument needAgreeCount must between 1 and admins count");
				return "";
			}
			if (admins.size() >= 2 && needAgreeCount < 2) {
				set_error(1, "argument needAgreeCount must between 2 and admins count when admins count >= 2");
				return "";
			}
			jsondiff::JsonObject proposal;
			proposal["creator"] = sender.caller_address;
			proposal["address"] = addr;
			proposal["add"] = add;
			proposal["needAgreeCount"] = needAgreeCount;
			proposal["votes"] = jsondiff::JsonObject();
			proposal["proposalStartBlockNumber"] = sender.block_number + 10; // only can vote when >= this block number
			set_contract_storage(contract_id, "current_change_admin_proposal", proposal);
			emit_event(contract_id, "AddedAdminChangeProposal", api_arg);
			return "";
		}
		std::string dgp_native_contract::vote_admin_api(const std::string& api_name, const std::string& api_arg) {

			auto admins = get_contract_storage(contract_id, "admins").as<jsondiff::JsonArray>();
			if (!is_address_in_admins(admins, sender.caller_address)) {
				set_error(1, "only admin can call this api");
				return "";
			}
			const auto& current_change_admin_proposal_json = get_contract_storage(contract_id, "current_change_admin_proposal");
			if (!current_change_admin_proposal_json.is_object()) {
				set_error(1, "change-admin-proposal not found to vote");
				return "";
			}
			auto current_change_admin_proposal = current_change_admin_proposal_json.as<jsondiff::JsonObject>();
			if (api_arg != "true" && api_arg != "false") {
				set_error(1, "argument format error, need format is: true or false");
				return "";
			}
			auto agree = ("true" == api_arg);
			bool add = current_change_admin_proposal["add"].as_bool();
			const auto& addr = current_change_admin_proposal["address"].as_string();
			vote_for_proposal(current_change_admin_proposal, agree, admins.size(),
				[&](const jsondiff::JsonObject&) {
				if (add) {
					admins.push_back(addr);
					set_contract_storage(contract_id, "admins", admins);
					set_contract_storage(contract_id, "current_change_admin_proposal", jsondiff::JsonValue()); // clear current admin-change proposal
					emit_event(contract_id, "AddedAdmin", addr);
				}
				else {
					// clear current admin-change and params-change proposal because of admins count's reduction
					jsondiff::JsonArray new_admins;
					for (const auto& item : admins) {
						if (item.as_string() != addr)
							new_admins.push_back(item.as_string());
					}
					set_contract_storage(contract_id, "admins", new_admins);
					set_contract_storage(contract_id, "current_change_admin_proposal", jsondiff::JsonValue());
					set_contract_storage(contract_id, "current_change_params_proposal", jsondiff::JsonValue());
					emit_event(contract_id, "RemovedAdmin", addr);
				}
			},
				[&](const jsondiff::JsonObject&) {
				set_contract_storage(contract_id, "current_change_admin_proposal", jsondiff::JsonValue());
				emit_event(contract_id, "VoteFailed", "");
			},
				[&](const jsondiff::JsonObject& proposal) {
				set_contract_storage(contract_id, "current_change_admin_proposal", proposal);
				emit_event(contract_id, "VoteUpdated", api_arg);
			});
			return "";
		}

		static jsondiff::JsonArray make_json_pair(const jsondiff::JsonValue& left, const jsondiff::JsonValue& right)
		{
			jsondiff::JsonArray result;
			result.push_back(left);
			result.push_back(right);
			return result;
		}

		static jsondiff::JsonArray parse_json_object_to_json_array(const jsondiff::JsonObject& obj) {
			jsondiff::JsonArray result;
			for (const auto& p : obj) {
				const auto& value = p.value();
				if (value.is_object()) {
					result.push_back(make_json_pair(p.key(), parse_json_object_to_json_array(value.as<jsondiff::JsonObject>())));
				}
				else {
					result.push_back(make_json_pair(p.key(), p.value()));
				}
			}
			return result;
		}

		std::string dgp_native_contract::current_change_admin_proposal_api(const std::string& api_name, const std::string& api_arg) {
			const auto& current_change_admin_proposal_json = get_contract_storage(contract_id, "current_change_admin_proposal");
			if (!current_change_admin_proposal_json.is_object()) {
				return "null";
			}
			const auto& current_change_admin_proposal = current_change_admin_proposal_json.as<jsondiff::JsonObject>();
			const auto& result = parse_json_object_to_json_array(current_change_admin_proposal);
			return jsondiff::json_dumps(result);
		}

		std::string dgp_native_contract::current_change_params_proposal_api(const std::string& api_name, const std::string& api_arg) {
			const auto& proposal_json = get_contract_storage(contract_id, "current_change_params_proposal");
			if (!proposal_json.is_object()) {
				return "null";
			}
			const auto& proposal = proposal_json.as<jsondiff::JsonObject>();
			const auto& result = parse_json_object_to_json_array(proposal);
			return jsondiff::json_dumps(result);
		}

		std::string dgp_native_contract::cancel_change_admin_proposal_api(const std::string& api_name, const std::string& api_arg)
		{
			const auto& current_change_admin_proposal_json = get_contract_storage(contract_id, "current_change_admin_proposal");
			if (!current_change_admin_proposal_json.is_object()) {
				set_error(1, "there is no change-admin-proposal now");
				return "";
			}
			const auto& current_change_admin_proposal = current_change_admin_proposal_json.as<jsondiff::JsonObject>();
			const auto& proposal_creator = current_change_admin_proposal["creator"].as_string();
			if (sender.caller_address != proposal_creator) {
				set_error(1, "only proposal creator can cancel it");
				return "";
			}
			set_contract_storage(contract_id, "current_change_admin_proposal", jsondiff::JsonValue());
			return "";
		}

		void dgp_native_contract::vote_for_proposal(jsondiff::JsonObject& proposal, bool agree, uint32_t admins_count,
			std::function<void(const jsondiff::JsonObject&)> proposal_success_handler,
			std::function<void(const jsondiff::JsonObject&)> proposal_fail_handler,
			std::function<void(const jsondiff::JsonObject&)> vote_handler)
		{
			auto votes = proposal["votes"].as<jsondiff::JsonObject>();
			if (votes.find(sender.caller_address) != votes.end()) {
				set_error(1, "you voted this proposal before");
				return;
			}
			auto proposalStartBlockNumber = proposal["proposalStartBlockNumber"].as_int64();
			if (sender.block_number < proposalStartBlockNumber) {
				set_error(1, "This proposal has not been effective and cannot vote");
				return;
			}
			votes[sender.caller_address] = agree;
			proposal["votes"] = votes;
			// check whether proposal ended
			int32_t agree_count = 0;
			int32_t disagree_count = 0;
			for (const auto& p : votes) {
				bool item = p.value().as_bool();
				if (item)
					agree_count++;
				else
					disagree_count++;
			}
			auto needAgreeCount = proposal["needAgreeCount"].as_uint64();

			if (agree_count >= needAgreeCount) {
				// vote successfully
				proposal_success_handler(proposal);
			}
			else if (disagree_count > admins_count - needAgreeCount) {
				// vote failed
				proposal_fail_handler(proposal);
			}
			else {
				// update votes
				vote_handler(proposal);
			}
		}

		std::string dgp_native_contract::vote_change_param_api(const std::string& api_name, const std::string& api_arg)
		{
			const auto& admins = get_contract_storage(contract_id, "admins").as<jsondiff::JsonArray>();
			if (!is_address_in_admins(admins, sender.caller_address)) {
				set_error(1, "only admin can call this api");
				return "";
			}
			const auto& current_change_params_proposal_json = get_contract_storage(contract_id, "current_change_params_proposal");
			if (!current_change_params_proposal_json.is_object()) {
				set_error(1, "can't find a change-params-proposal");
				return "";
			}
			if (api_arg != "true" && api_arg != "false") {
				set_error(1, "argument format error, need format is: true or false");
				return "";
			}
			auto agree = ("true" == api_arg);
			auto current_change_params_proposal = current_change_params_proposal_json.as<jsondiff::JsonObject>();

			std::string property_name = current_change_params_proposal["property"].as_string();
			const auto& property_value = current_change_params_proposal["value"];

			vote_for_proposal(current_change_params_proposal, agree, admins.size(),
				[&](const jsondiff::JsonObject& proposal) {
				set_dgp_param(property_name, property_value);
				set_contract_storage(contract_id, "current_change_params_proposal", jsondiff::JsonValue());
				emit_event(contract_id, "VoteSuccess", property_name);
			},
				[&](const jsondiff::JsonObject& proposal) {
				set_contract_storage(contract_id, "current_change_params_proposal", jsondiff::JsonValue());
				emit_event(contract_id, "ParamsChangeVoteFailed", property_name);
			},
				[&](const jsondiff::JsonObject& proposal) {
				set_contract_storage(contract_id, "current_change_params_proposal", proposal);
				emit_event(contract_id, "ParamsChangeVoteUpdated", api_arg);
			});
			return "";
		}

		std::string dgp_native_contract::get_dgp_param_json_string(const std::string& param_name)
		{
			const auto& dgp_params = get_contract_storage(contract_id, "dgp_params").as<jsondiff::JsonObject>();
			if (dgp_params.find(param_name) == dgp_params.end())
				return jsondiff::json_dumps(jsondiff::JsonValue());
			else
				return jsondiff::json_dumps(dgp_params[param_name]);
		}

		static const std::map<std::string, DgpChangeIntParamType> dgp_params_int_mapping = {
			{ "min_gas_price", DgpChangeIntParamType::DGP_MIN_GAS_PRICE_CHANGE_ITEM },
			{ "block_gas_limit", DgpChangeIntParamType::DGP_BLOCK_GAS_LIMIT_CHANGE_ITEM },
			{ "min_gas_count", DgpChangeIntParamType::DGP_MIN_GAS_COUNT_CHANGE_ITEM },
			{ "max_contract_bytecode_store_fee_gas_count", DgpChangeIntParamType::DGP_MAX_CONTRACT_BYTECODE_STORE_FEE_GAS_COUNT_CHANGE_ITEM }
		};

		void dgp_native_contract::set_dgp_param(const std::string& param_name, const jsondiff::JsonValue& value)
		{
			auto dgp_params = get_contract_storage(contract_id, "dgp_params").as<jsondiff::JsonObject>();
			dgp_params[param_name] = value;
			set_contract_storage(contract_id, "dgp_params", dgp_params);
			if (dgp_params_int_mapping.find(param_name) != dgp_params_int_mapping.end() && value.is_integer()) {
				auto& int_param_type = dgp_params_int_mapping.at(param_name);
				_contract_exec_result.dgp_int_params_changes[int_param_type] = value.as_int64();
			}
		}

		std::string dgp_native_contract::min_gas_price_api(const std::string& api_name, const std::string& api_arg)
		{
			const auto& value_json_str = get_dgp_param_json_string("min_gas_price");
			return value_json_str;
		}
		std::string dgp_native_contract::block_gas_limit_api(const std::string& api_name, const std::string& api_arg) {
			const auto& value_json_str = get_dgp_param_json_string("block_gas_limit");
			return value_json_str;
		}
		std::string dgp_native_contract::min_gas_count_api(const std::string& api_name, const std::string& api_arg) {
			const auto& value_json_str = get_dgp_param_json_string("min_gas_count");
			return value_json_str;
		}

		std::string dgp_native_contract::max_contract_bytecode_store_fee_gas_count_api(const std::string& api_name, const std::string& api_arg) {
			const auto& value_json_str = get_dgp_param_json_string("max_contract_bytecode_store_fee_gas_count");
			return value_json_str;
		}

		bool dgp_native_contract::create_int_param_proposal(const std::string& property_name, const std::string& api_arg, uint32_t admins_count)
		{
			// argument: integer_value,needAgreeCount
			const auto& current_change_params_proposal = get_contract_storage(contract_id, "current_change_params_proposal");
			if (!current_change_params_proposal.is_null()) {
				set_error(1, "can't create new change-params-proposal when a proposal already exists");
				return false;
			}
			int64_t value = 0;
			uint32_t needAgreeCount = 0;
			{
				auto pos = api_arg.find_first_of(',');
				if (pos <= 0) {
					set_error(1, "argument format error, need format is integer_value,needAgreeCount");
					return false;
				}
				const auto& value_str = api_arg.substr(0, pos);
				const auto& need_agree_count_str = api_arg.substr(pos + 1);
				try {
					value = boost::lexical_cast<int64_t>(value_str);
					needAgreeCount = boost::lexical_cast<uint32_t>(need_agree_count_str);
					if (needAgreeCount<1 || needAgreeCount > admins_count)
						throw ::contract::storage::ContractStorageException("need agree count illegal");
					if (admins_count >= 2 && needAgreeCount < 2)
						throw ::contract::storage::ContractStorageException("need agree count illegal");
				}
				catch (const std::exception& e) {
					set_error(1, "argument format error, need format is integer_value,needAgreeCount");
					return false;
				}
			}
			const auto& dgp_params = get_contract_storage(contract_id, "dgp_params").as<jsondiff::JsonObject>();
			if (dgp_params[property_name].as_int64() == value) {
				set_error(1, "param value not changed, proposal failed");
				return false;
			}
			jsondiff::JsonObject proposal;
			proposal["creator"] = sender.caller_address;
			proposal["property"] = property_name;
			proposal["needAgreeCount"] = needAgreeCount;
			proposal["value"] = value;
			proposal["votes"] = jsondiff::JsonObject();
			proposal["proposalStartBlockNumber"] = sender.block_number + 10; // only can vote when >= this block number
			set_contract_storage(contract_id, "current_change_params_proposal", proposal);
			emit_event(contract_id, "AddedChangeParamsProposal", api_arg);
			return true;
		}

		std::string dgp_native_contract::set_min_gas_price_api(const std::string& api_name, const std::string& api_arg)
		{
			// argument: integer_value,needAgreeCount
			const auto& admins = get_contract_storage(contract_id, "admins").as<jsondiff::JsonArray>();
			if (!is_address_in_admins(admins, sender.caller_address)) {
				set_error(1, "only admin can call this api");
				return "";
			}
			create_int_param_proposal("min_gas_price", api_arg, admins.size());
			return "";
		}

		std::string dgp_native_contract::set_block_gas_limit_api(const std::string& api_name, const std::string& api_arg)
		{
			// argument: integer_value,needAgreeCount
			const auto& admins = get_contract_storage(contract_id, "admins").as<jsondiff::JsonArray>();
			if (!is_address_in_admins(admins, sender.caller_address)) {
				set_error(1, "only admin can call this api");
				return "";
			}
			create_int_param_proposal("block_gas_limit", api_arg, admins.size());
			return "";
		}

		std::string dgp_native_contract::set_min_gas_count_api(const std::string& api_name, const std::string& api_arg)
		{
			// argument: integer_value,needAgreeCount
			const auto& admins = get_contract_storage(contract_id, "admins").as<jsondiff::JsonArray>();
			if (!is_address_in_admins(admins, sender.caller_address)) {
				set_error(1, "only admin can call this api");
				return "";
			}
			create_int_param_proposal("min_gas_count", api_arg, admins.size());
			return "";
		}

		std::string dgp_native_contract::set_max_contract_bytecode_store_fee_gas_count_api(const std::string& api_name, const std::string& api_arg) {
			// argument: integer_value,needAgreeCount
			const auto& admins = get_contract_storage(contract_id, "admins").as<jsondiff::JsonArray>();
			if (!is_address_in_admins(admins, sender.caller_address)) {
				set_error(1, "only admin can call this api");
				return "";
			}
			create_int_param_proposal("max_contract_bytecode_store_fee_gas_count", api_arg, admins.size());
			return "";
		}

		ContractExecResult dgp_native_contract::invoke(const std::string& api_name, const std::string& api_arg) {
			ContractExecResult result;
			std::map<std::string, std::function<std::string (const std::string&, const std::string&)> > apis_mapping = {
				{ "init", std::bind(&dgp_native_contract::init_api, this, std::placeholders::_1, std::placeholders::_2) },
				{ "admins", std::bind(&dgp_native_contract::admins_api, this, std::placeholders::_1, std::placeholders::_2) },
				{ "create_change_admin_proposal", std::bind(&dgp_native_contract::create_change_admin_proposal_api, this, std::placeholders::_1, std::placeholders::_2) },
				{ "vote_admin", std::bind(&dgp_native_contract::vote_admin_api, this, std::placeholders::_1, std::placeholders::_2) },
				{ "current_change_admin_proposal", std::bind(&dgp_native_contract::current_change_admin_proposal_api, this, std::placeholders::_1, std::placeholders::_2) },
				{ "current_change_params_proposal", std::bind(&dgp_native_contract::current_change_params_proposal_api, this, std::placeholders::_1, std::placeholders::_2) },
				{ "cancel_change_admin_proposal", std::bind(&dgp_native_contract::cancel_change_admin_proposal_api, this, std::placeholders::_1, std::placeholders::_2) },
				{ "vote_change_param", std::bind(&dgp_native_contract::vote_change_param_api, this, std::placeholders::_1, std::placeholders::_2) },
				{ "min_gas_price", std::bind(&dgp_native_contract::min_gas_price_api, this, std::placeholders::_1, std::placeholders::_2) },
				{ "set_min_gas_price", std::bind(&dgp_native_contract::set_min_gas_price_api, this, std::placeholders::_1, std::placeholders::_2) },
				{ "block_gas_limit", std::bind(&dgp_native_contract::block_gas_limit_api, this, std::placeholders::_1, std::placeholders::_2) },
				{ "set_block_gas_limit", std::bind(&dgp_native_contract::set_block_gas_limit_api, this, std::placeholders::_1, std::placeholders::_2) },
				{ "min_gas_count", std::bind(&dgp_native_contract::min_gas_count_api, this, std::placeholders::_1, std::placeholders::_2) },
				{ "set_min_gas_count", std::bind(&dgp_native_contract::set_min_gas_count_api, this, std::placeholders::_1, std::placeholders::_2) },
				{ "max_contract_bytecode_store_fee_gas_count", std::bind(&dgp_native_contract::max_contract_bytecode_store_fee_gas_count_api, this, std::placeholders::_1, std::placeholders::_2) },
				{ "set_max_contract_bytecode_store_fee_gas_count", std::bind(&dgp_native_contract::set_max_contract_bytecode_store_fee_gas_count_api, this, std::placeholders::_1, std::placeholders::_2) }
			};
			if (apis_mapping.find(api_name) != apis_mapping.end()) {
				result.api_result = apis_mapping[api_name](api_name, api_arg);
			} else {
				result.exit_code = 1;
				result.error_message = std::string("Can't find dgp api ") + api_name;
				return result;
			}

			merge_storage_changes_to_exec_result();
			result.contract_storage_changes = _contract_exec_result.contract_storage_changes;
			return result;
		}

    }
}

max_stars_repo_name: YihaoPeng/UnitedBitcoin

max_issues_repo_name: YihaoPeng/UnitedBitcoin

max_forks_repo_name: YihaoPeng/UnitedBitcoin


text:
#pragma once
#include "genesis_exception.hpp"
#include "posting_rules.hpp"
#include <eosio/chain/types.hpp>
#include <eosio/chain/asset.hpp>
#include <eosio/chain/authority.hpp>
#include <fc/reflect/reflect.hpp>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>

namespace cyberway { namespace genesis {

using namespace eosio::chain;
namespace bfs = boost::filesystem;

struct genesis_info {

    struct file_hash {
        bfs::path path;
        fc::sha256 hash;
    };

    struct permission {
        permission_name name;
        fc::optional<unsigned> threshold;
        fc::optional<permission_name> parent;   // defaults: "" for "owner" permission; "owner" for "active"; "active" for others; numeric id if adding permission to existing account
        std::string key;                // can use "INITIAL" and "key/weight"; only empty "key" can co-exist with non-empty "keys" and vice-versa
        std::vector<string> keys;       // can use "INITIAL" and "key/weight"
        std::vector<string> accounts;   // can use "name@permission" and "name@permission/weight"
        std::vector<string> waits;      // can use "wait/weight"

        void init() {
            if (key.length() > 0) {
                keys.emplace_back(key);
                key = "";
            }
        }

        permission_name get_parent() const {
            if (parent) {
                return *parent;
            }
            return name == N(owner) ? N() : name == N(active) ? N(owner) : N(active);
        }

        std::vector<key_weight> key_weights(const public_key_type& initial_key) const {
            std::vector<key_weight> r;
            for (const auto& key: keys) {
                auto k_weight = split_weight(key);
                r.emplace_back(key_weight{k_weight.first == "INITIAL" ? initial_key : public_key_type(k_weight.first), k_weight.second});
            }
            return r;
        }

        std::pair<string,weight_type> split_weight(const string& str) const {
            std::vector<string> parts;
            split(parts, str, boost::algorithm::is_any_of("/"));
            unsigned weight = parts.size() == 1 ? 1 : boost::lexical_cast<weight_type>(parts[1]);
            return std::make_pair(parts[0], weight);
        }

        std::vector<permission_level_weight> perm_levels(account_name code, std::function<account_name(const std::string&)> name_resolver) const {
            std::vector<permission_level_weight> r;
            for (const auto& a: accounts) {
                std::vector<string> parts;
                auto perm_weight = split_weight(a);
                split(parts, perm_weight.first, boost::algorithm::is_any_of("@"));
                auto acc = parts[0].size() == 0 ? code : name_resolver(parts[0]);
                auto perm = account_name(parts.size() == 1 ? "" : parts[1].c_str());
                r.emplace_back(permission_level_weight{permission_level{acc, perm}, perm_weight.second});
            }
            return r;
        }

        std::vector<wait_weight> wait_weights() const {
            std::vector<wait_weight> r;
            for (const auto& w: waits) {
                auto a = split_weight(w);
                r.emplace_back(wait_weight{boost::lexical_cast<uint32_t>(a.first), a.second});
            }
            return r;
        }

        authority make_authority(const public_key_type& initial_key, account_name code, std::function<account_name(const std::string&)> name_resolver) const {
            return authority(threshold ? *threshold : 1, key_weights(initial_key), perm_levels(code, name_resolver), wait_weights());
        }
    };

    struct account {
        account_name name;
        fc::optional<bool> update;
        fc::optional<bool> privileged;
        std::vector<permission> permissions;
        fc::optional<file_hash> abi;
        fc::optional<file_hash> code;
        fc::optional<asset> sys_balance;
        fc::optional<asset> sys_staked;
        fc::optional<string> prod_key;
    };

    bfs::path state_file;   // ? file_hash
    bfs::path genesis_json;
    std::vector<account> accounts;

    struct auth_link {
        using names_pair = std::pair<name,name>;
        string permission;              // account@permission
        std::vector<string> links;      // each link is "contract:action" or "contract:*" (simple "contract" also works)

        names_pair get_permission() const {
            std::vector<string> parts;
            split(parts, permission, boost::algorithm::is_any_of("@"));
            return names_pair{name(parts[0]), name(parts[1])};
        }

        std::vector<names_pair> get_links() const {
            std::vector<names_pair> r;
            for (const auto& l: links) {
                std::vector<string> parts;
                split(parts, l, boost::algorithm::is_any_of(":"));
                name action{parts.size() > 1 ? string_to_name(parts[1].c_str()) : 0};
                r.emplace_back(names_pair{name(parts[0]), action});
            }
            return r;
        }
    };
    std::vector<auth_link> auth_links;

    struct transit_account_authority {
        name name;
        std::string username;
        std::vector<permission> permissions;
    };
    std::vector<transit_account_authority> transit_account_authorities;

    struct delegateuse_item {
        std::string from;
        std::string to;
        std::string quantity;
    };
    std::vector<delegateuse_item> delegateuse;

    struct table {
        struct row {
            string scope;   // can be name/symbol/symbol_code
            name payer;
            uint64_t pk;
            variant data;

            uint64_t get_scope() const {
                name maybe_name{string_to_name(scope.c_str())};
                if (maybe_name.to_string() == scope) {
                    return name{scope}.value;
                } else if (scope.find(',') != string::npos) {
                    return symbol::from_string(scope).value();
                } else {
                    return symbol::from_string("0,"+scope).to_symbol_code().value;
                }
            }
        };
        account_name code;
        name table;
        string abi_type;
        std::vector<row> rows;
    };
    std::vector<table> tables;

    // parameters
    struct golos_config {
        std::string domain;

        struct golos_names {
            account_name issuer;
            account_name control;
            account_name emission;
            account_name vesting;
            account_name posting;
            account_name social;
            account_name charge;
            account_name memo;
        } names;

        struct recovery_params {
            uint32_t wait_days;
        } recovery;

        int64_t max_supply = 0;
        int64_t sys_max_supply = 0;

        struct start_trx_params {
            uint16_t delay_minutes = 60;
            uint16_t expiration_hours = 3;
        } start_trx;
    } golos;

    struct stake_params {
        bool enabled = false;
        std::vector<uint8_t> max_proxies;
        int64_t depriving_window;
        int64_t min_own_staked_for_election = 0;
    };
    struct funds_share {
        account_name name;
        // value multiplied to base CYBER supply. use num/denom to avoid floating point
        int64_t numerator;
        int64_t denominator;
    };

    struct parameters {
        uint8_t initial_prod_count = 0;
        stake_params stake;
        posting_rules posting_rules;
        std::vector<funds_share> funds;
    } params;

    struct ee_parameters {
        struct ee_history_days {
            uint16_t transfers = 30;
            uint16_t withdraws = 30;
            uint16_t rewards = 30;
        } history_days;
    } ee_params;

    void init() {
        for (auto& a: accounts) {
            for (auto& p: a.permissions) {
                EOS_ASSERT(p.key.length() == 0 || p.keys.size() == 0, genesis_exception,
                    "Account ${a} permission can't contain both `key` and `keys` fields at the same time", ("a",a.name));
                p.init();
            }
        }
        for (auto& a: transit_account_authorities) {
            for (auto& p: a.permissions) {
                EOS_ASSERT(p.key.length() == 0 || p.keys.size() == 0, genesis_exception,
                    "Transit account ${a} permission can't contain both `key` and `keys` fields at the same time", ("a",a.name));
                p.init();
            }
        }
    }
};

}} // cyberway::genesis

FC_REFLECT(cyberway::genesis::genesis_info::file_hash, (path)(hash))
FC_REFLECT(cyberway::genesis::genesis_info::permission, (name)(threshold)(parent)(key)(keys)(accounts)(waits))
FC_REFLECT(cyberway::genesis::genesis_info::account, (name)(update)(privileged)(permissions)(abi)(code)(sys_balance)(sys_staked)(prod_key))
FC_REFLECT(cyberway::genesis::genesis_info::auth_link, (permission)(links))
FC_REFLECT(cyberway::genesis::genesis_info::transit_account_authority, (username)(permissions))
FC_REFLECT(cyberway::genesis::genesis_info::delegateuse_item, (from)(to)(quantity))
FC_REFLECT(cyberway::genesis::genesis_info::table::row, (scope)(payer)(pk)(data))
FC_REFLECT(cyberway::genesis::genesis_info::table, (code)(table)(abi_type)(rows))
FC_REFLECT(cyberway::genesis::genesis_info::golos_config::golos_names,
    (issuer)(control)(emission)(vesting)(posting)(social)(charge)(memo))
FC_REFLECT(cyberway::genesis::genesis_info::golos_config::recovery_params, (wait_days))
FC_REFLECT(cyberway::genesis::genesis_info::golos_config::start_trx_params, (delay_minutes)(expiration_hours))
FC_REFLECT(cyberway::genesis::genesis_info::golos_config,
    (domain)(names)(recovery)(max_supply)(sys_max_supply)(start_trx))
FC_REFLECT(cyberway::genesis::genesis_info::stake_params,
    (enabled)(max_proxies)(depriving_window)(min_own_staked_for_election))
FC_REFLECT(cyberway::genesis::genesis_info::funds_share, (name)(numerator)(denominator))
FC_REFLECT(cyberway::genesis::genesis_info::parameters, (initial_prod_count)(stake)(posting_rules)(funds))
FC_REFLECT(cyberway::genesis::genesis_info::ee_parameters::ee_history_days, (transfers)(withdraws)(rewards))
FC_REFLECT(cyberway::genesis::genesis_info::ee_parameters, (history_days))
FC_REFLECT(cyberway::genesis::genesis_info, (state_file)(genesis_json)(accounts)(auth_links)(transit_account_authorities)(delegateuse)(tables)(golos)(params)(ee_params))

ext: hpp

max_stars_repo_name: GolosChain/eos

max_issues_repo_name: GolosChain/eos

max_forks_repo_name: GolosChain/eos


text:
//---------------------------------------------------------------------------//
// Copyright (c) 2013-2014 Kyle Lutz <kyle.r.lutz@gmail.com>
//
// Distributed under 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
//
// See http://kylelutz.github.com/compute for more information.
//---------------------------------------------------------------------------//

#define BOOST_TEST_MODULE TestDynamicBitset
#include <boost/test/unit_test.hpp>

#include <boost/compute/algorithm/copy.hpp>
#include <boost/compute/container/dynamic_bitset.hpp>

#include "check_macros.hpp"
#include "context_setup.hpp"

namespace compute = boost::compute;

BOOST_AUTO_TEST_CASE(set_and_test)
{
    compute::dynamic_bitset<> bits(1024, queue);

    bits.set(1, queue);
    BOOST_CHECK(bits.test(1, queue) == true);
    BOOST_CHECK(bits.test(2, queue) == false);

    bits.set(1, false, queue);
    BOOST_CHECK(bits.test(1, queue) == false);
    BOOST_CHECK(bits.test(2, queue) == false);
}

BOOST_AUTO_TEST_CASE(count)
{
    compute::dynamic_bitset<> bits(1024, queue);
    BOOST_CHECK_EQUAL(bits.count(queue), size_t(0));

    bits.set(1, queue);
    bits.set(8, queue);
    bits.set(129, queue);
    BOOST_CHECK_EQUAL(bits.count(queue), size_t(3));

    bits.set(8, false, queue);
    BOOST_CHECK_EQUAL(bits.count(queue), size_t(2));

    bits.reset(queue);
    BOOST_CHECK_EQUAL(bits.count(queue), size_t(0));
}

BOOST_AUTO_TEST_CASE(resize)
{
    compute::dynamic_bitset<> bits(0, queue);
    BOOST_CHECK_EQUAL(bits.size(), size_t(0));
    BOOST_CHECK_EQUAL(bits.empty(), true);
    BOOST_CHECK_EQUAL(bits.count(queue), size_t(0));

    bits.resize(100, queue);
    BOOST_CHECK_EQUAL(bits.size(), size_t(100));
    BOOST_CHECK_EQUAL(bits.empty(), false);
    BOOST_CHECK_EQUAL(bits.count(queue), size_t(0));

    bits.set(42, true, queue);
    BOOST_CHECK_EQUAL(bits.count(queue), size_t(1));

    bits.resize(0, queue);
    BOOST_CHECK_EQUAL(bits.size(), size_t(0));
    BOOST_CHECK_EQUAL(bits.empty(), true);
    BOOST_CHECK_EQUAL(bits.count(queue), size_t(0));
}

BOOST_AUTO_TEST_CASE(none_and_any)
{
    compute::dynamic_bitset<> bits(1024, queue);
    BOOST_CHECK(bits.any(queue) == false);
    BOOST_CHECK(bits.none(queue) == true);

    bits.set(1023, queue);
    BOOST_CHECK(bits.any(queue) == true);
    BOOST_CHECK(bits.none(queue) == false);

    bits.set(1023, false, queue);
    BOOST_CHECK(bits.any(queue) == false);
    BOOST_CHECK(bits.none(queue) == true);

    bits.set(1, queue);
    BOOST_CHECK(bits.any(queue) == true);
    BOOST_CHECK(bits.none(queue) == false);

    bits.reset(queue);
    BOOST_CHECK(bits.any(queue) == false);
    BOOST_CHECK(bits.none(queue) == true);
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: bastiankoe/compute

max_issues_repo_name: bastiankoe/compute

max_forks_repo_name: bastiankoe/compute


text:
//  Copyright John Maddock 2007.
//  Copyright Matt Borland 2021.
//  Use, modification and distribution are 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_MATH_POLICY_HPP
#define BOOST_MATH_POLICY_HPP

#include <boost/math/tools/config.hpp>
#include <boost/math/tools/mp.hpp>
#include <limits>
#include <type_traits>
#include <cmath>
#include <cstdint>
#include <cstddef>

namespace mp = boost::math::tools::meta_programming;

namespace boost{ namespace math{

namespace tools{

template <class T>
BOOST_MATH_CONSTEXPR int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T)) BOOST_NOEXCEPT;
template <class T>
BOOST_MATH_CONSTEXPR T epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T)) BOOST_MATH_NOEXCEPT(T);

}

namespace policies{

//
// Define macros for our default policies, if they're not defined already:
//
// Special cases for exceptions disabled first:
//
#ifdef BOOST_NO_EXCEPTIONS
#  ifndef BOOST_MATH_DOMAIN_ERROR_POLICY
#    define BOOST_MATH_DOMAIN_ERROR_POLICY errno_on_error
#  endif
#  ifndef BOOST_MATH_POLE_ERROR_POLICY
#     define BOOST_MATH_POLE_ERROR_POLICY errno_on_error
#  endif
#  ifndef BOOST_MATH_OVERFLOW_ERROR_POLICY
#     define BOOST_MATH_OVERFLOW_ERROR_POLICY errno_on_error
#  endif
#  ifndef BOOST_MATH_EVALUATION_ERROR_POLICY
#     define BOOST_MATH_EVALUATION_ERROR_POLICY errno_on_error
#  endif
#  ifndef BOOST_MATH_ROUNDING_ERROR_POLICY
#     define BOOST_MATH_ROUNDING_ERROR_POLICY errno_on_error
#  endif
#endif
//
// Then the regular cases:
//
#ifndef BOOST_MATH_DOMAIN_ERROR_POLICY
#define BOOST_MATH_DOMAIN_ERROR_POLICY throw_on_error
#endif
#ifndef BOOST_MATH_POLE_ERROR_POLICY
#define BOOST_MATH_POLE_ERROR_POLICY throw_on_error
#endif
#ifndef BOOST_MATH_OVERFLOW_ERROR_POLICY
#define BOOST_MATH_OVERFLOW_ERROR_POLICY throw_on_error
#endif
#ifndef BOOST_MATH_EVALUATION_ERROR_POLICY
#define BOOST_MATH_EVALUATION_ERROR_POLICY throw_on_error
#endif
#ifndef BOOST_MATH_ROUNDING_ERROR_POLICY
#define BOOST_MATH_ROUNDING_ERROR_POLICY throw_on_error
#endif
#ifndef BOOST_MATH_UNDERFLOW_ERROR_POLICY
#define BOOST_MATH_UNDERFLOW_ERROR_POLICY ignore_error
#endif
#ifndef BOOST_MATH_DENORM_ERROR_POLICY
#define BOOST_MATH_DENORM_ERROR_POLICY ignore_error
#endif
#ifndef BOOST_MATH_INDETERMINATE_RESULT_ERROR_POLICY
#define BOOST_MATH_INDETERMINATE_RESULT_ERROR_POLICY ignore_error
#endif
#ifndef BOOST_MATH_DIGITS10_POLICY
#define BOOST_MATH_DIGITS10_POLICY 0
#endif
#ifndef BOOST_MATH_PROMOTE_FLOAT_POLICY
#define BOOST_MATH_PROMOTE_FLOAT_POLICY true
#endif
#ifndef BOOST_MATH_PROMOTE_DOUBLE_POLICY
#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
#define BOOST_MATH_PROMOTE_DOUBLE_POLICY false
#else
#define BOOST_MATH_PROMOTE_DOUBLE_POLICY true
#endif
#endif
#ifndef BOOST_MATH_DISCRETE_QUANTILE_POLICY
#define BOOST_MATH_DISCRETE_QUANTILE_POLICY integer_round_outwards
#endif
#ifndef BOOST_MATH_ASSERT_UNDEFINED_POLICY
#define BOOST_MATH_ASSERT_UNDEFINED_POLICY true
#endif
#ifndef BOOST_MATH_MAX_SERIES_ITERATION_POLICY
#define BOOST_MATH_MAX_SERIES_ITERATION_POLICY 1000000
#endif
#ifndef BOOST_MATH_MAX_ROOT_ITERATION_POLICY
#define BOOST_MATH_MAX_ROOT_ITERATION_POLICY 200
#endif

#define BOOST_MATH_META_INT(Type, name, Default)                                                \
   template <Type N = Default>                                                                  \
   class name : public std::integral_constant<int, N>{};                                        \
                                                                                \
   namespace detail{                                                                            \
   template <Type N>                                                                            \
   char test_is_valid_arg(const name<N>* = nullptr);                                            \
   char test_is_default_arg(const name<Default>* = nullptr);                                    \
                                                                                \
   template <typename T>                                                                        \
   class is_##name##_imp                                                                        \
   {                                                                                \
   private:                                                                                \
      template <Type N>                                                                         \
      static char test(const name<N>* = nullptr);                                               \
      static double test(...);                                                                  \
   public:                                                                                \
      static constexpr bool value = sizeof(test(static_cast<T*>(0))) == sizeof(char);           \
   };                                                                                \
   }                                                                                \
                                                                                \
   template <typename T>                                                                        \
   class is_##name                                                                              \
   {                                                                                \
   public:                                                                                \
      static constexpr bool value = boost::math::policies::detail::is_##name##_imp<T>::value;   \
      using type = std::integral_constant<bool, value>;                                         \
   };

#define BOOST_MATH_META_BOOL(name, Default)                                                     \
   template <bool N = Default>                                                                  \
   class name : public std::integral_constant<bool, N>{};                                       \
                                                                                \
   namespace detail{                                                                            \
   template <bool N>                                                                            \
   char test_is_valid_arg(const name<N>* = nullptr);                                            \
   char test_is_default_arg(const name<Default>* = nullptr);                                    \
                                                                                \
   template <typename T>                                                                        \
   class is_##name##_imp                                                                        \
   {                                                                                \
   private:                                                                                \
      template <bool N>                                                                         \
      static char test(const name<N>* = nullptr);                                               \
      static double test(...);                                                                  \
   public:                                                                                \
      static constexpr bool value = sizeof(test(static_cast<T*>(0))) == sizeof(char);           \
   };                                                                                \
   }                                                                                \
                                                                                \
   template <typename T>                                                                        \
   class is_##name                                                                              \
   {                                                                                \
   public:                                                                                \
      static constexpr bool value = boost::math::policies::detail::is_##name##_imp<T>::value;   \
      using type = std::integral_constant<bool, value>;                                         \
   };

//
// Begin by defining policy types for error handling:
//
enum error_policy_type
{
   throw_on_error = 0,
   errno_on_error = 1,
   ignore_error = 2,
   user_error = 3
};

BOOST_MATH_META_INT(error_policy_type, domain_error, BOOST_MATH_DOMAIN_ERROR_POLICY)
BOOST_MATH_META_INT(error_policy_type, pole_error, BOOST_MATH_POLE_ERROR_POLICY)
BOOST_MATH_META_INT(error_policy_type, overflow_error, BOOST_MATH_OVERFLOW_ERROR_POLICY)
BOOST_MATH_META_INT(error_policy_type, underflow_error, BOOST_MATH_UNDERFLOW_ERROR_POLICY)
BOOST_MATH_META_INT(error_policy_type, denorm_error, BOOST_MATH_DENORM_ERROR_POLICY)
BOOST_MATH_META_INT(error_policy_type, evaluation_error, BOOST_MATH_EVALUATION_ERROR_POLICY)
BOOST_MATH_META_INT(error_policy_type, rounding_error, BOOST_MATH_ROUNDING_ERROR_POLICY)
BOOST_MATH_META_INT(error_policy_type, indeterminate_result_error, BOOST_MATH_INDETERMINATE_RESULT_ERROR_POLICY)

//
// Policy types for internal promotion:
//
BOOST_MATH_META_BOOL(promote_float, BOOST_MATH_PROMOTE_FLOAT_POLICY)
BOOST_MATH_META_BOOL(promote_double, BOOST_MATH_PROMOTE_DOUBLE_POLICY)
BOOST_MATH_META_BOOL(assert_undefined, BOOST_MATH_ASSERT_UNDEFINED_POLICY)
//
// Policy types for discrete quantiles:
//
enum discrete_quantile_policy_type
{
   real,
   integer_round_outwards,
   integer_round_inwards,
   integer_round_down,
   integer_round_up,
   integer_round_nearest
};

BOOST_MATH_META_INT(discrete_quantile_policy_type, discrete_quantile, BOOST_MATH_DISCRETE_QUANTILE_POLICY)
//
// Precision:
//
BOOST_MATH_META_INT(int, digits10, BOOST_MATH_DIGITS10_POLICY)
BOOST_MATH_META_INT(int, digits2, 0)
//
// Iterations:
//
BOOST_MATH_META_INT(unsigned long, max_series_iterations, BOOST_MATH_MAX_SERIES_ITERATION_POLICY)
BOOST_MATH_META_INT(unsigned long, max_root_iterations, BOOST_MATH_MAX_ROOT_ITERATION_POLICY)
//
// Define the names for each possible policy:
//
#define BOOST_MATH_PARAMETER(name)\
   BOOST_PARAMETER_TEMPLATE_KEYWORD(name##_name)\
   BOOST_PARAMETER_NAME(name##_name)

struct default_policy{};

namespace detail{
//
// Trait to work out bits precision from digits10 and digits2:
//
template <class Digits10, class Digits2>
struct precision
{
   //
   // Now work out the precision:
   //
   using digits2_type = typename std::conditional<
      (Digits10::value == 0),
      digits2<0>,
      digits2<((Digits10::value + 1) * 1000L) / 301L>
   >::type;
public:
#ifdef BOOST_BORLANDC
   using type = typename std::conditional<
      (Digits2::value > ::boost::math::policies::detail::precision<Digits10,Digits2>::digits2_type::value),
      Digits2, digits2_type>::type;
#else
   using type = typename std::conditional<
      (Digits2::value > digits2_type::value),
      Digits2, digits2_type>::type;
#endif
};

double test_is_valid_arg(...);
double test_is_default_arg(...);
char test_is_valid_arg(const default_policy*);
char test_is_default_arg(const default_policy*);

template <typename T>
class is_valid_policy_imp
{
public:
   static constexpr bool value = sizeof(boost::math::policies::detail::test_is_valid_arg(static_cast<T*>(0))) == sizeof(char);
};

template <typename T>
class is_valid_policy
{
public:
   static constexpr bool value = boost::math::policies::detail::is_valid_policy_imp<T>::value;
};

template <typename T>
class is_default_policy_imp
{
public:
   static constexpr bool value = sizeof(boost::math::policies::detail::test_is_default_arg(static_cast<T*>(0))) == sizeof(char);
};

template <typename T>
class is_default_policy
{
public:
   static constexpr bool value = boost::math::policies::detail::is_default_policy_imp<T>::value;
   using type = std::integral_constant<bool, value>;

   template <typename U>
   struct apply
   {
      using type = is_default_policy<U>;
   };
};

template <class Seq, class T, std::size_t N>
struct append_N
{
   using type = typename append_N<mp::mp_push_back<Seq, T>, T, N-1>::type;
};

template <class Seq, class T>
struct append_N<Seq, T, 0>
{
   using type = Seq;
};

//
// Traits class to work out what template parameters our default
// policy<> class will have when modified for forwarding:
//
template <bool f, bool d>
struct default_args
{
   typedef promote_float<false> arg1;
   typedef promote_double<false> arg2;
};

template <>
struct default_args<false, false>
{
   typedef default_policy arg1;
   typedef default_policy arg2;
};

template <>
struct default_args<true, false>
{
   typedef promote_float<false> arg1;
   typedef default_policy arg2;
};

template <>
struct default_args<false, true>
{
   typedef promote_double<false> arg1;
   typedef default_policy arg2;
};

typedef default_args<BOOST_MATH_PROMOTE_FLOAT_POLICY, BOOST_MATH_PROMOTE_DOUBLE_POLICY>::arg1 forwarding_arg1;
typedef default_args<BOOST_MATH_PROMOTE_FLOAT_POLICY, BOOST_MATH_PROMOTE_DOUBLE_POLICY>::arg2 forwarding_arg2;

} // detail

//
// Now define the policy type with enough arguments to handle all
// the policies:
//
template <typename A1  = default_policy,
          typename A2  = default_policy,
          typename A3  = default_policy,
          typename A4  = default_policy,
          typename A5  = default_policy,
          typename A6  = default_policy,
          typename A7  = default_policy,
          typename A8  = default_policy,
          typename A9  = default_policy,
          typename A10 = default_policy,
          typename A11 = default_policy,
          typename A12 = default_policy,
          typename A13 = default_policy>
class policy
{
private:
   //
   // Validate all our arguments:
   //
   static_assert(::boost::math::policies::detail::is_valid_policy<A1>::value, "::boost::math::policies::detail::is_valid_policy<A1>::value");
   static_assert(::boost::math::policies::detail::is_valid_policy<A2>::value, "::boost::math::policies::detail::is_valid_policy<A2>::value");
   static_assert(::boost::math::policies::detail::is_valid_policy<A3>::value, "::boost::math::policies::detail::is_valid_policy<A3>::value");
   static_assert(::boost::math::policies::detail::is_valid_policy<A4>::value, "::boost::math::policies::detail::is_valid_policy<A4>::value");
   static_assert(::boost::math::policies::detail::is_valid_policy<A5>::value, "::boost::math::policies::detail::is_valid_policy<A5>::value");
   static_assert(::boost::math::policies::detail::is_valid_policy<A6>::value, "::boost::math::policies::detail::is_valid_policy<A6>::value");
   static_assert(::boost::math::policies::detail::is_valid_policy<A7>::value, "::boost::math::policies::detail::is_valid_policy<A7>::value");
   static_assert(::boost::math::policies::detail::is_valid_policy<A8>::value, "::boost::math::policies::detail::is_valid_policy<A8>::value");
   static_assert(::boost::math::policies::detail::is_valid_policy<A9>::value, "::boost::math::policies::detail::is_valid_policy<A9>::value");
   static_assert(::boost::math::policies::detail::is_valid_policy<A10>::value, "::boost::math::policies::detail::is_valid_policy<A10>::value");
   static_assert(::boost::math::policies::detail::is_valid_policy<A11>::value, "::boost::math::policies::detail::is_valid_policy<A11>::value");
   static_assert(::boost::math::policies::detail::is_valid_policy<A12>::value, "::boost::math::policies::detail::is_valid_policy<A12>::value");
   static_assert(::boost::math::policies::detail::is_valid_policy<A13>::value, "::boost::math::policies::detail::is_valid_policy<A13>::value");
   //
   // Typelist of the arguments:
   //
   using arg_list = mp::mp_list<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13>;
   static constexpr std::size_t arg_list_size = mp::mp_size<arg_list>::value;

   template<typename A, typename B, bool b>
   struct pick_arg
   {
      using type = A;
   };

   template<typename A, typename B>
   struct pick_arg<A, B, false>
   {
      using type = mp::mp_at<arg_list, B>;
   };

   template<typename Fn, typename Default>
   class arg_type
   {
   private:
      using index = mp::mp_find_if_q<arg_list, Fn>;
      static constexpr bool end = (index::value >= arg_list_size);
   public:
      using type = typename pick_arg<Default, index, end>::type;
   };

   // Work out the base 2 and 10 precisions to calculate the public precision_type:
   using digits10_type = typename arg_type<mp::mp_quote_trait<is_digits10>, digits10<>>::type;
   using bits_precision_type = typename arg_type<mp::mp_quote_trait<is_digits2>, digits2<>>::type;

public:

   // Error Types:
   using domain_error_type = typename arg_type<mp::mp_quote_trait<is_domain_error>, domain_error<>>::type;
   using pole_error_type = typename arg_type<mp::mp_quote_trait<is_pole_error>, pole_error<>>::type;
   using overflow_error_type = typename arg_type<mp::mp_quote_trait<is_overflow_error>, overflow_error<>>::type;
   using underflow_error_type = typename arg_type<mp::mp_quote_trait<is_underflow_error>, underflow_error<>>::type;
   using denorm_error_type = typename arg_type<mp::mp_quote_trait<is_denorm_error>, denorm_error<>>::type;
   using evaluation_error_type = typename arg_type<mp::mp_quote_trait<is_evaluation_error>, evaluation_error<>>::type;
   using rounding_error_type = typename arg_type<mp::mp_quote_trait<is_rounding_error>, rounding_error<>>::type;
   using indeterminate_result_error_type = typename arg_type<mp::mp_quote_trait<is_indeterminate_result_error>, indeterminate_result_error<>>::type;

   // Precision:
   using precision_type = typename detail::precision<digits10_type, bits_precision_type>::type;

   // Internal promotion:
   using promote_float_type = typename arg_type<mp::mp_quote_trait<is_promote_float>, promote_float<>>::type;
   using promote_double_type = typename arg_type<mp::mp_quote_trait<is_promote_double>, promote_double<>>::type;

   // Discrete quantiles:
   using discrete_quantile_type = typename arg_type<mp::mp_quote_trait<is_discrete_quantile>, discrete_quantile<>>::type;

   // Mathematically undefined properties:
   using assert_undefined_type = typename arg_type<mp::mp_quote_trait<is_assert_undefined>, assert_undefined<>>::type;

   // Max iterations:
   using max_series_iterations_type = typename arg_type<mp::mp_quote_trait<is_max_series_iterations>, max_series_iterations<>>::type;
   using max_root_iterations_type = typename arg_type<mp::mp_quote_trait<is_max_root_iterations>, max_root_iterations<>>::type;
};

//
// These full specializations are defined to reduce the amount of
// template instantiations that have to take place when using the default
// policies, they have quite a large impact on compile times:
//
template <>
class policy<default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy>
{
public:
   using domain_error_type = domain_error<>;
   using pole_error_type = pole_error<>;
   using overflow_error_type = overflow_error<>;
   using underflow_error_type = underflow_error<>;
   using denorm_error_type = denorm_error<>;
   using evaluation_error_type = evaluation_error<>;
   using rounding_error_type = rounding_error<>;
   using indeterminate_result_error_type = indeterminate_result_error<>;
#if BOOST_MATH_DIGITS10_POLICY == 0
   using precision_type = digits2<>;
#else
   using precision_type = detail::precision<digits10<>, digits2<>>::type;
#endif
   using promote_float_type = promote_float<>;
   using promote_double_type = promote_double<>;
   using discrete_quantile_type = discrete_quantile<>;
   using assert_undefined_type = assert_undefined<>;
   using max_series_iterations_type = max_series_iterations<>;
   using max_root_iterations_type = max_root_iterations<>;
};

template <>
struct policy<detail::forwarding_arg1, detail::forwarding_arg2, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy>
{
public:
   using domain_error_type = domain_error<>;
   using pole_error_type = pole_error<>;
   using overflow_error_type = overflow_error<>;
   using underflow_error_type = underflow_error<>;
   using denorm_error_type = denorm_error<>;
   using evaluation_error_type = evaluation_error<>;
   using rounding_error_type = rounding_error<>;
   using indeterminate_result_error_type = indeterminate_result_error<>;
#if BOOST_MATH_DIGITS10_POLICY == 0
   using precision_type = digits2<>;
#else
   using precision_type = detail::precision<digits10<>, digits2<>>::type;
#endif
   using promote_float_type = promote_float<false>;
   using promote_double_type = promote_double<false>;
   using discrete_quantile_type = discrete_quantile<>;
   using assert_undefined_type = assert_undefined<>;
   using max_series_iterations_type = max_series_iterations<>;
   using max_root_iterations_type = max_root_iterations<>;
};

template <typename Policy,
          typename A1  = default_policy,
          typename A2  = default_policy,
          typename A3  = default_policy,
          typename A4  = default_policy,
          typename A5  = default_policy,
          typename A6  = default_policy,
          typename A7  = default_policy,
          typename A8  = default_policy,
          typename A9  = default_policy,
          typename A10 = default_policy,
          typename A11 = default_policy,
          typename A12 = default_policy,
          typename A13 = default_policy>
class normalise
{
private:
   using arg_list = mp::mp_list<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13>;
   static constexpr std::size_t arg_list_size = mp::mp_size<arg_list>::value;

   template<typename A, typename B, bool b>
   struct pick_arg
   {
      using type = A;
   };

   template<typename A, typename B>
   struct pick_arg<A, B, false>
   {
      using type = mp::mp_at<arg_list, B>;
   };

   template<typename Fn, typename Default>
   class arg_type
   {
   private:
      using index = mp::mp_find_if_q<arg_list, Fn>;
      static constexpr bool end = (index::value >= arg_list_size);
   public:
      using type = typename pick_arg<Default, index, end>::type;
   };

   // Error types:
   using domain_error_type = typename arg_type<mp::mp_quote_trait<is_domain_error>, typename Policy::domain_error_type>::type;
   using pole_error_type = typename arg_type<mp::mp_quote_trait<is_pole_error>, typename Policy::pole_error_type>::type;
   using overflow_error_type = typename arg_type<mp::mp_quote_trait<is_overflow_error>, typename Policy::overflow_error_type>::type;
   using underflow_error_type = typename arg_type<mp::mp_quote_trait<is_underflow_error>, typename Policy::underflow_error_type>::type;
   using denorm_error_type = typename arg_type<mp::mp_quote_trait<is_denorm_error>, typename Policy::denorm_error_type>::type;
   using evaluation_error_type = typename arg_type<mp::mp_quote_trait<is_evaluation_error>, typename Policy::evaluation_error_type>::type;
   using rounding_error_type = typename arg_type<mp::mp_quote_trait<is_rounding_error>, typename Policy::rounding_error_type>::type;
   using indeterminate_result_error_type = typename arg_type<mp::mp_quote_trait<is_indeterminate_result_error>, typename Policy::indeterminate_result_error_type>::type;

   // Precision:
   using digits10_type = typename arg_type<mp::mp_quote_trait<is_digits10>, digits10<>>::type;
   using bits_precision_type = typename arg_type<mp::mp_quote_trait<is_digits2>, typename Policy::precision_type>::type;
   using precision_type = typename detail::precision<digits10_type, bits_precision_type>::type;

   // Internal promotion:
   using promote_float_type = typename arg_type<mp::mp_quote_trait<is_promote_float>, typename Policy::promote_float_type>::type;
   using promote_double_type = typename arg_type<mp::mp_quote_trait<is_promote_double>, typename Policy::promote_double_type>::type;

   // Discrete quantiles:
   using discrete_quantile_type = typename arg_type<mp::mp_quote_trait<is_discrete_quantile>, typename Policy::discrete_quantile_type>::type;

   // Mathematically undefined properties:
   using assert_undefined_type = typename arg_type<mp::mp_quote_trait<is_assert_undefined>, typename Policy::assert_undefined_type>::type;

   // Max iterations:
   using max_series_iterations_type = typename arg_type<mp::mp_quote_trait<is_max_series_iterations>, typename Policy::max_series_iterations_type>::type;
   using max_root_iterations_type = typename arg_type<mp::mp_quote_trait<is_max_root_iterations>, typename Policy::max_root_iterations_type>::type;

   // Define a typelist of the policies:
   using result_list = mp::mp_list<
      domain_error_type,
      pole_error_type,
      overflow_error_type,
      underflow_error_type,
      denorm_error_type,
      evaluation_error_type,
      rounding_error_type,
      indeterminate_result_error_type,
      precision_type,
      promote_float_type,
      promote_double_type,
      discrete_quantile_type,
      assert_undefined_type,
      max_series_iterations_type,
      max_root_iterations_type>;

   // Remove all the policies that are the same as the default:
   using fn = mp::mp_quote_trait<detail::is_default_policy>;
   using reduced_list = mp::mp_remove_if_q<result_list, fn>;

   // Pad out the list with defaults:
   using result_type = typename detail::append_N<reduced_list, default_policy, (14UL - mp::mp_size<reduced_list>::value)>::type;

public:
   using type = policy<
      mp::mp_at_c<result_type, 0>,
      mp::mp_at_c<result_type, 1>,
      mp::mp_at_c<result_type, 2>,
      mp::mp_at_c<result_type, 3>,
      mp::mp_at_c<result_type, 4>,
      mp::mp_at_c<result_type, 5>,
      mp::mp_at_c<result_type, 6>,
      mp::mp_at_c<result_type, 7>,
      mp::mp_at_c<result_type, 8>,
      mp::mp_at_c<result_type, 9>,
      mp::mp_at_c<result_type, 10>,
      mp::mp_at_c<result_type, 11>,
      mp::mp_at_c<result_type, 12>
      >;
};

// Full specialisation to speed up compilation of the common case:
template <>
struct normalise<policy<>,
          promote_float<false>,
          promote_double<false>,
          discrete_quantile<>,
          assert_undefined<>,
          default_policy,
          default_policy,
          default_policy,
          default_policy,
          default_policy,
          default_policy,
          default_policy>
{
   using type = policy<detail::forwarding_arg1, detail::forwarding_arg2>;
};

template <>
struct normalise<policy<detail::forwarding_arg1, detail::forwarding_arg2>,
          promote_float<false>,
          promote_double<false>,
          discrete_quantile<>,
          assert_undefined<>,
          default_policy,
          default_policy,
          default_policy,
          default_policy,
          default_policy,
          default_policy,
          default_policy>
{
   using type = policy<detail::forwarding_arg1, detail::forwarding_arg2>;
};

inline constexpr policy<> make_policy() noexcept
{ return policy<>(); }

template <class A1>
inline constexpr typename normalise<policy<>, A1>::type make_policy(const A1&) noexcept
{
   typedef typename normalise<policy<>, A1>::type result_type;
   return result_type();
}

template <class A1, class A2>
inline constexpr typename normalise<policy<>, A1, A2>::type make_policy(const A1&, const A2&) noexcept
{
   typedef typename normalise<policy<>, A1, A2>::type result_type;
   return result_type();
}

template <class A1, class A2, class A3>
inline constexpr typename normalise<policy<>, A1, A2, A3>::type make_policy(const A1&, const A2&, const A3&) noexcept
{
   typedef typename normalise<policy<>, A1, A2, A3>::type result_type;
   return result_type();
}

template <class A1, class A2, class A3, class A4>
inline constexpr typename normalise<policy<>, A1, A2, A3, A4>::type make_policy(const A1&, const A2&, const A3&, const A4&) noexcept
{
   typedef typename normalise<policy<>, A1, A2, A3, A4>::type result_type;
   return result_type();
}

template <class A1, class A2, class A3, class A4, class A5>
inline constexpr typename normalise<policy<>, A1, A2, A3, A4, A5>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&) noexcept
{
   typedef typename normalise<policy<>, A1, A2, A3, A4, A5>::type result_type;
   return result_type();
}

template <class A1, class A2, class A3, class A4, class A5, class A6>
inline constexpr typename normalise<policy<>, A1, A2, A3, A4, A5, A6>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&) noexcept
{
   typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6>::type result_type;
   return result_type();
}

template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
inline constexpr typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&, const A7&) noexcept
{
   typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7>::type result_type;
   return result_type();
}

template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
inline constexpr typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&, const A7&, const A8&) noexcept
{
   typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8>::type result_type;
   return result_type();
}

template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
inline constexpr typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8, A9>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&, const A7&, const A8&, const A9&) noexcept
{
   typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8, A9>::type result_type;
   return result_type();
}

template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
inline constexpr typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&, const A7&, const A8&, const A9&, const A10&) noexcept
{
   typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>::type result_type;
   return result_type();
}

template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11>
inline constexpr typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&, const A7&, const A8&, const A9&, const A10&, const A11&) noexcept
{
   typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>::type result_type;
   return result_type();
}

//
// Traits class to handle internal promotion:
//
template <class Real, class Policy>
struct evaluation
{
   typedef Real type;
};

template <class Policy>
struct evaluation<float, Policy>
{
   using type = typename std::conditional<Policy::promote_float_type::value, double, float>::type;
};

template <class Policy>
struct evaluation<double, Policy>
{
   using type = typename std::conditional<Policy::promote_double_type::value, long double, double>::type;
};

template <class Real, class Policy>
struct precision
{
   static_assert((std::numeric_limits<Real>::radix == 2) || ((std::numeric_limits<Real>::is_specialized == 0) || (std::numeric_limits<Real>::digits == 0)),
   "(std::numeric_limits<Real>::radix == 2) || ((std::numeric_limits<Real>::is_specialized == 0) || (std::numeric_limits<Real>::digits == 0))");
#ifndef BOOST_BORLANDC
   using precision_type = typename Policy::precision_type;
   using type = typename std::conditional<
      ((std::numeric_limits<Real>::is_specialized == 0) || (std::numeric_limits<Real>::digits == 0)),
      // Possibly unknown precision:
      precision_type,
      typename std::conditional<
         ((std::numeric_limits<Real>::digits <= precision_type::value)
         || (Policy::precision_type::value <= 0)),
         // Default case, full precision for RealType:
         digits2< std::numeric_limits<Real>::digits>,
         // User customised precision:
         precision_type
      >::type
   >::type;
#else
   using precision_type = typename Policy::precision_type;
   using digits_t = std::integral_constant<int, std::numeric_limits<Real>::digits>;
   using spec_t = std::integral_constant<bool, std::numeric_limits<Real>::is_specialized>;
   using type = typename std::conditional<
      (spec_t::value == true std::true_type || digits_t::value == 0),
      // Possibly unknown precision:
      precision_type,
      typename std::conditional<
         (digits_t::value <= precision_type::value || precision_type::value <= 0),
         // Default case, full precision for RealType:
         digits2< std::numeric_limits<Real>::digits>,
         // User customised precision:
         precision_type
      >::type
   >::type;
#endif
};

#ifdef BOOST_MATH_USE_FLOAT128

template <class Policy>
struct precision<BOOST_MATH_FLOAT128_TYPE, Policy>
{
   typedef std::integral_constant<int, 113> type;
};

#endif

namespace detail{

template <class T, class Policy>
inline BOOST_MATH_CONSTEXPR int digits_imp(std::true_type const&) noexcept
{
   static_assert( std::numeric_limits<T>::is_specialized, "std::numeric_limits<T>::is_specialized");
   typedef typename boost::math::policies::precision<T, Policy>::type p_t;
   return p_t::value;
}

template <class T, class Policy>
inline BOOST_MATH_CONSTEXPR int digits_imp(std::false_type const&) noexcept
{
   return tools::digits<T>();
}

} // namespace detail

template <class T, class Policy>
inline BOOST_MATH_CONSTEXPR int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) noexcept
{
   typedef std::integral_constant<bool, std::numeric_limits<T>::is_specialized > tag_type;
   return detail::digits_imp<T, Policy>(tag_type());
}
template <class T, class Policy>
inline constexpr int digits_base10(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) noexcept
{
   return boost::math::policies::digits<T, Policy>() * 301 / 1000L;
}

template <class Policy>
inline constexpr unsigned long get_max_series_iterations() noexcept
{
   typedef typename Policy::max_series_iterations_type iter_type;
   return iter_type::value;
}

template <class Policy>
inline constexpr unsigned long get_max_root_iterations() noexcept
{
   typedef typename Policy::max_root_iterations_type iter_type;
   return iter_type::value;
}

namespace detail{

template <class T, class Digits, class Small, class Default>
struct series_factor_calc
{
   static T get() noexcept(std::is_floating_point<T>::value)
   {
      return ldexp(T(1.0), 1 - Digits::value);
   }
};

template <class T, class Digits>
struct series_factor_calc<T, Digits, std::true_type, std::true_type>
{
   static BOOST_MATH_CONSTEXPR T get() noexcept(std::is_floating_point<T>::value)
   {
      return boost::math::tools::epsilon<T>();
   }
};
template <class T, class Digits>
struct series_factor_calc<T, Digits, std::true_type, std::false_type>
{
   static BOOST_MATH_CONSTEXPR T get() noexcept(std::is_floating_point<T>::value)
   {
      return 1 / static_cast<T>(static_cast<std::uintmax_t>(1u) << (Digits::value - 1));
   }
};
template <class T, class Digits>
struct series_factor_calc<T, Digits, std::false_type, std::true_type>
{
   static BOOST_MATH_CONSTEXPR T get() noexcept(std::is_floating_point<T>::value)
   {
      return boost::math::tools::epsilon<T>();
   }
};

template <class T, class Policy>
inline BOOST_MATH_CONSTEXPR T get_epsilon_imp(std::true_type const&) noexcept(std::is_floating_point<T>::value)
{
   static_assert(std::numeric_limits<T>::is_specialized, "std::numeric_limits<T>::is_specialized");
   static_assert(std::numeric_limits<T>::radix == 2, "std::numeric_limits<T>::radix == 2");

   typedef typename boost::math::policies::precision<T, Policy>::type p_t;
   typedef std::integral_constant<bool, p_t::value <= std::numeric_limits<std::uintmax_t>::digits> is_small_int;
   typedef std::integral_constant<bool, p_t::value >= std::numeric_limits<T>::digits> is_default_value;
   return series_factor_calc<T, p_t, is_small_int, is_default_value>::get();
}

template <class T, class Policy>
inline BOOST_MATH_CONSTEXPR T get_epsilon_imp(std::false_type const&) noexcept(std::is_floating_point<T>::value)
{
   return tools::epsilon<T>();
}

} // namespace detail

template <class T, class Policy>
inline BOOST_MATH_CONSTEXPR T get_epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(std::is_floating_point<T>::value)
{
   typedef std::integral_constant<bool, (std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::radix == 2)) > tag_type;
   return detail::get_epsilon_imp<T, Policy>(tag_type());
}

namespace detail{

template <class A1,
          class A2,
          class A3,
          class A4,
          class A5,
          class A6,
          class A7,
          class A8,
          class A9,
          class A10,
          class A11>
char test_is_policy(const policy<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11>*);
double test_is_policy(...);

template <typename P>
class is_policy_imp
{
public:
   static constexpr bool value = (sizeof(::boost::math::policies::detail::test_is_policy(static_cast<P*>(0))) == sizeof(char));
};

}

template <typename P>
class is_policy
{
public:
   static constexpr bool value = boost::math::policies::detail::is_policy_imp<P>::value;
   using type = std::integral_constant<bool, value>;
};

//
// Helper traits class for distribution error handling:
//
template <class Policy>
struct constructor_error_check
{
   using domain_error_type = typename Policy::domain_error_type;
   using type = typename std::conditional<
      (domain_error_type::value == throw_on_error) || (domain_error_type::value == user_error) || (domain_error_type::value == errno_on_error),
      std::true_type,
      std::false_type>::type;
};

template <class Policy>
struct method_error_check
{
   using domain_error_type = typename Policy::domain_error_type;
   using type = typename std::conditional<
      (domain_error_type::value == throw_on_error) && (domain_error_type::value != user_error),
      std::false_type,
      std::true_type>::type;
};
//
// Does the Policy ever throw on error?
//
template <class Policy>
struct is_noexcept_error_policy
{
   typedef typename Policy::domain_error_type               t1;
   typedef typename Policy::pole_error_type                 t2;
   typedef typename Policy::overflow_error_type             t3;
   typedef typename Policy::underflow_error_type            t4;
   typedef typename Policy::denorm_error_type               t5;
   typedef typename Policy::evaluation_error_type           t6;
   typedef typename Policy::rounding_error_type             t7;
   typedef typename Policy::indeterminate_result_error_type t8;

   static constexpr bool value =
      ((t1::value != throw_on_error) && (t1::value != user_error)
      && (t2::value != throw_on_error) && (t2::value != user_error)
      && (t3::value != throw_on_error) && (t3::value != user_error)
      && (t4::value != throw_on_error) && (t4::value != user_error)
      && (t5::value != throw_on_error) && (t5::value != user_error)
      && (t6::value != throw_on_error) && (t6::value != user_error)
      && (t7::value != throw_on_error) && (t7::value != user_error)
      && (t8::value != throw_on_error) && (t8::value != user_error));
};

}}} // namespaces

#endif // BOOST_MATH_POLICY_HPP


text: #include <boost/fusion/include/remove.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
//          Copyright Oliver Kowalke 2009.
// Distributed under 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_COROUTINES_DETAIL_STACK_TUPLE_H
#define BOOST_COROUTINES_DETAIL_STACK_TUPLE_H

#include <cstddef>

#include <boost/config.hpp>

#include <boost/coroutine/detail/config.hpp>
#include <boost/coroutine/stack_context.hpp>

#ifdef BOOST_HAS_ABI_HEADERS
#  include BOOST_ABI_PREFIX
#endif

namespace boost {
namespace coroutines {
namespace detail {

template< typename StackAllocator >
struct stack_tuple
{
    coroutines::stack_context   stack_ctx;
    StackAllocator              stack_alloc;

    stack_tuple( StackAllocator const& stack_alloc_, std::size_t size) :
        stack_ctx(),
        stack_alloc( stack_alloc_)
    { stack_alloc.allocate( stack_ctx, size); }

    ~stack_tuple()
    { stack_alloc.deallocate( stack_ctx); }
};

}}}

#ifdef BOOST_HAS_ABI_HEADERS
#  include BOOST_ABI_SUFFIX
#endif

#endif // BOOST_COROUTINES_DETAIL_STACK_TUPLE_H

max_stars_repo_name: ballisticwhisper/boost

max_issues_repo_name: ballisticwhisper/boost

max_forks_repo_name: ballisticwhisper/boost


text:
//
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under 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)
//

#pragma once

#include <boost/asio.hpp>
#include <string>

#include "connection.hpp"
#include "connection_manager.hpp"
#include "request_handler.hpp"

namespace http
{
    namespace server
    {
        /// The top-level class of the HTTP server.
        class server
        {
        public:
          explicit server(const std::string& address, const std::string& port);
          void run();

        private:
          void doAccept();
          void doAwaitStop();

          boost::asio::io_service io_service_;
          boost::asio::signal_set signals_;
          boost::asio::ip::tcp::acceptor acceptor_;
          connection_manager connection_manager_;
          boost::asio::ip::tcp::socket socket_;
          request_handler request_handler_;

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