<commit_before>#include <iostream>
#include <string>
#include <algorithm>
#include <cstdlib>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/strong_components.hpp>
#include <boost/graph/graphviz.hpp>
#include <boost/program_options.hpp>
#include "float-semiring.h"
#include "free-semiring.h"
#include "semilinSetExp.h"
#include "matrix.h"
#include "polynomial.h"
#include "newton.h"
#include "commutativeRExp.h"
#include "parser.h"

template <typename SR>
struct VertexProp {
	std::string name;   // used for graphviz output
	VarPtr var;         // var and rex combines the equations in the vertex
	Polynomial<SR> rex;
};

// group the equations to SCCs
template <typename SR>
std::vector<std::vector<std::pair<VarPtr, Polynomial<SR>>>> group_by_scc(std::vector<std::pair<VarPtr, Polynomial<SR>>> equations, bool graphviz_output)
{
	// create map of variables to [0..n]. this is used to enumerate important variables in a clean way from 0 to n during graph construction
	std::map<VarPtr, int> var_key;

	// build the graph
	boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, VertexProp<SR>> graph(equations.size());
	for(auto e_it = equations.begin(); e_it != equations.end(); ++e_it)
	{
		// if the variable is not yet in the map insert it together with the size of
		// the map. this way we get a unique identifier for the variable counting from 0 to n
		if(var_key.find(e_it->first) == var_key.end())
			var_key.insert(var_key.begin(), std::pair<VarPtr,int>(e_it->first,var_key.size()));
		int a = var_key.find(e_it->first)->second; // variable key
		graph[a].var = e_it->first; // store VarPtr to the vertex
		graph[a].name = e_it->first->string(); // store the name to the vertex
		graph[a].rex = e_it->second; // store the regular expression to the vertex

		auto v = e_it->second.get_variables(); // all variables of this rule;
		for(auto v_it = v.begin(); v_it != v.end(); ++v_it)
		{
			if(var_key.find(*v_it) == var_key.end()) // variable is not yet in the map
				var_key.insert(var_key.begin(), std::pair<VarPtr,int>(*v_it,var_key.size()));
			int b = var_key.find(*v_it)->second; // variable key
			boost::add_edge(a, b, graph);
		}
	} // graph is complete

	if(graphviz_output)
	{
		// output the created graph to graph.dot
		boost::dynamic_properties dp;
		dp.property("label", boost::get(&VertexProp<SR>::name, graph)); // vertex name is the name of the equation
		dp.property("node_id", get(boost::vertex_index, graph)); // this is needed
		std::ofstream outf("graph.dot");
		boost::write_graphviz_dp(outf, graph, dp);
	}

	// calculate strong connected components and store them in 'component'
	std::vector<int> component(boost::num_vertices(graph));
	boost::strong_components(graph,&component[0]);

	// group neccessary equations together
	int num_comp = *std::max_element(component.begin(), component.end()) + 1; // find the number of components
	std::vector<std::vector<std::pair<VarPtr,Polynomial<SR>>>> grouped_equations;
	grouped_equations.resize(num_comp);

	// iterate over all vertices (0 to n)
	// collect the necessary variables + equations for every component
	for (unsigned int j = 0; j != component.size(); ++j)
	{
		//std::cout << j << ", " << graph[j].var << " is in component " << component[j] << std::endl;
		grouped_equations[component[j]].push_back(std::pair<VarPtr,Polynomial<SR>>(graph[j].var, graph[j].rex));
	}

	return grouped_equations;
}

// apply the newton method to the given input
template <typename SR>
std::map<VarPtr, SR> apply_newton(std::vector<std::pair<VarPtr, Polynomial<SR>>> equations, bool scc, bool iteration_flag, int iterations, bool graphviz_output)
{
	// TODO: sanity checks on the input!

	// generate an instance of the newton solver
	Newton<SR> newton;

	// if we use the scc method, group the equations
	// the outer vector contains SCCs starting with a bottom SCC at 0
	std::vector<std::vector<std::pair<VarPtr,Polynomial<SR>>>> equations2;
	if(scc)
	{
		auto tmp = group_by_scc(equations, graphviz_output);
		equations2.insert(equations2.begin(), tmp.begin(), tmp.end());
	}
	else if (!scc)
	{
		equations2.push_back(equations);
	}

	// this holds the solution
	std::map<VarPtr, SR> solution;

	// the same loop is used for both the scc and the non-scc variant
	// in the non-scc variant, we just run once through the loop
	//for(auto it1 = equations2.begin(); it != equations2.end(); ++it)
	for(unsigned int j = 0; j != equations2.size(); ++j)
	{
		// use the solutions to get rid of variables in the remaining equations
		// does nothing in the first round
		std::vector<std::pair<VarPtr, Polynomial<SR>>> tmp1;
		for(auto it = equations2[j].begin(); it != equations2[j].end(); ++it)
		{ // it = (VarPtr, Polynomial[SR])
			auto tmp2 = it->second.partial_eval(solution);
			tmp1.push_back(std::pair<VarPtr, Polynomial<SR>>(it->first, tmp2));
		}
		// replace old equations with simplified ones
		equations2[j] = tmp1;

		// dynamic iterations
		if(!iteration_flag)
			// for commutative SRs newton has converged after n+1 iterations, so use this number as default
			iterations = equations2[j].size() + 1;

		// do some real work here
		std::map<VarPtr, SR> result = newton.solve_fixpoint(equations2[j], iterations);

		// copy the results into the solution map
		solution.insert(result.begin(), result.end());
	}

	return solution;
}

template <typename SR>
std::string result_string(std::map<VarPtr,SR> result)
{
	std::stringstream ss;
	for(auto r_it = result.begin(); r_it != result.end(); ++r_it)
		ss << r_it->first << " == " << r_it->second << std::endl;
	return ss.str();
}

int main(int argc, char* argv[])
{
	namespace po = boost::program_options;

	po::options_description desc("Allowed options");
	desc.add_options()
		( "scc", "apply newton method iteratively to strongly connected components of the equation graph" )
		( "help,h", "print this help message" )
		( "iterations,i", po::value<int>(), "specify the number of newton iterations. default is optimal number" )
		//( "verbose", "enable verbose output" )
		//( "debug", "enable debug output" )
		( "test", "just for testing purposes ... explicit test defined in main()" )
		( "file,f", po::value<std::string>(), "input file" )
		( "float", "float semiring" )
		( "rexp", "commutative regular expression semiring" )
		( "slset", "explicit semilinear sets semiring (as vectors)" )
		( "graphviz", "create the file graph.dot with the equation graph" )
		;

	po::variables_map vm;
	po::store(po::parse_command_line(argc, argv, desc), vm);
	po::notify(vm);

	if(vm.count("test")) {
		Newton<SemilinSetExp> newton;
		std::vector<VarPtr> variables;
		variables.push_back(Var::getVar("x"));
		std::cout << "- newton (cnt-SR):" << std::endl;

		std::vector<Polynomial<SemilinSetExp> > polynomials;
		Polynomial<SemilinSetExp> f1 = Polynomial<SemilinSetExp>({
		Monomial<SemilinSetExp>(SemilinSetExp(Var::getVar("a")), {Var::getVar("x"),Var::getVar("x")}),
		Monomial<SemilinSetExp>(SemilinSetExp(Var::getVar("c")), {}) });

		polynomials.push_back(f1);

		Matrix<SemilinSetExp> result = newton.solve_fixpoint(polynomials, variables, 2);
		std::cout << result << std::endl;

/*		auto s1 = CommutativeRExp(Var::getVar("a"));
		auto s2 = CommutativeRExp(Var::getVar("b"));
		auto m1 = Matrix<CommutativeRExp>(1,1,{s1});
		auto m2 = Matrix<CommutativeRExp>(1,1,{s2});
*/

		// this actually led to a strange bug with the ublas-matrix implementation!!
/*		auto s1 = SemilinSetExp(Var::getVar("a"));
		auto s2 = SemilinSetExp(Var::getVar("b"));
		auto m1 = Matrix<SemilinSetExp>(1,1,{s1});
		auto m2 = Matrix<SemilinSetExp>(1,1,{s2});

		auto m3 = m1*m2;
		std::cout << m3;
*/
		return 0;
	}

	if(vm.count("help"))
	{
		std::cout << desc << std::endl;
		return 0;
	}

	int iterations=0;
	if(vm.count("iterations"))
		iterations = vm["iterations"].as<int>();

	// check if we can do something useful
	if(!vm.count("float") && !vm.count("rexp") && !vm.count("slset")) // check for all compatible parameters
	{
		std::cout << "Please supply a supported semiring :)" << std::endl;
		return 0;
	}

	std::vector<std::string> input;
	std::string line;
	if(vm.count("file"))
	{
		// we are reading the input from the given file
		std::ifstream file;
		file.open(vm["file"].as<std::string>(), std::ifstream::in);
		while(std::getline(file, line))
			input.push_back(line);
	}
	else
	{
		// we are reading from stdin
		while(std::getline(std::cin, line))
			input.push_back(line);
	}

	// join the input into one string
	std::string input_all = std::accumulate(input.begin(), input.end(), std::string(""));

	Parser p;

	if(vm.count("slset")) {
		std::vector<std::pair<VarPtr, Polynomial<SemilinSetExp>>> equations(p.slset_parser(input_all));
		if(equations.empty()) return -1;

		for(auto eq_it = equations.begin(); eq_it != equations.end(); ++eq_it)
		{
			std::cout << "* " << eq_it->first << " → " << eq_it->second << std::endl;
		}

		auto result = apply_newton<SemilinSetExp>(equations, vm.count("scc"), vm.count("iterations"), iterations, vm.count("graphviz"));
		std::cout << result_string(result) << std::endl;
	}
	else if(vm.count("rexp")) {
		// parse the input into a list of (Var → Polynomial[SR])
		std::vector<std::pair<VarPtr, Polynomial<CommutativeRExp>>> equations(p.rexp_parser(input_all));
		if(equations.empty()) return -1;

		for(auto eq_it = equations.begin(); eq_it != equations.end(); ++eq_it)
		{
			std::cout << "* " << eq_it->first << " → " << eq_it->second << std::endl;
		}

		// apply the newton method to the equations
		auto result = apply_newton<CommutativeRExp>(equations, vm.count("scc"), vm.count("iterations"), iterations, vm.count("graphviz"));
		std::cout << result_string(result) << std::endl;
	}
	else if(vm.count("float")) {
		std::vector<std::pair<VarPtr, Polynomial<FloatSemiring>>> equations(p.float_parser(input_all));
		if(equations.empty()) return -1;

		for(auto eq_it = equations.begin(); eq_it != equations.end(); ++eq_it)
		{
			std::cout << "* " << eq_it->first << " → " << eq_it->second << std::endl;
		}

		auto result = apply_newton<FloatSemiring>(equations, vm.count("scc"), vm.count("iterations"), iterations, vm.count("graphviz"));
		std::cout << result_string(result) << std::endl;
	}

	return 0;
}
<commit_msg>main: std::accumulate is defined in numeric header<commit_after>#include <iostream>
#include <string>
#include <algorithm>
#include <numeric>
#include <cstdlib>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/strong_components.hpp>
#include <boost/graph/graphviz.hpp>
#include <boost/program_options.hpp>
#include "float-semiring.h"
#include "semilinSetExp.h"
#include "matrix.h"
#include "polynomial.h"
#include "newton.h"
#include "commutativeRExp.h"
#include "parser.h"

template <typename SR>
struct VertexProp {
	std::string name;   // used for graphviz output
	VarPtr var;         // var and rex combines the equations in the vertex
	Polynomial<SR> rex;
};

// group the equations to SCCs
template <typename SR>
std::vector<std::vector<std::pair<VarPtr, Polynomial<SR>>>> group_by_scc(std::vector<std::pair<VarPtr, Polynomial<SR>>> equations, bool graphviz_output)
{
	// create map of variables to [0..n]. this is used to enumerate important variables in a clean way from 0 to n during graph construction
	std::map<VarPtr, int> var_key;

	// build the graph
	boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, VertexProp<SR>> graph(equations.size());
	for(auto e_it = equations.begin(); e_it != equations.end(); ++e_it)
	{
		// if the variable is not yet in the map insert it together with the size of
		// the map. this way we get a unique identifier for the variable counting from 0 to n
		if(var_key.find(e_it->first) == var_key.end())
			var_key.insert(var_key.begin(), std::pair<VarPtr,int>(e_it->first,var_key.size()));
		int a = var_key.find(e_it->first)->second; // variable key
		graph[a].var = e_it->first; // store VarPtr to the vertex
		graph[a].name = e_it->first->string(); // store the name to the vertex
		graph[a].rex = e_it->second; // store the regular expression to the vertex

		auto v = e_it->second.get_variables(); // all variables of this rule;
		for(auto v_it = v.begin(); v_it != v.end(); ++v_it)
		{
			if(var_key.find(*v_it) == var_key.end()) // variable is not yet in the map
				var_key.insert(var_key.begin(), std::pair<VarPtr,int>(*v_it,var_key.size()));
			int b = var_key.find(*v_it)->second; // variable key
			boost::add_edge(a, b, graph);
		}
	} // graph is complete

	if(graphviz_output)
	{
		// output the created graph to graph.dot
		boost::dynamic_properties dp;
		dp.property("label", boost::get(&VertexProp<SR>::name, graph)); // vertex name is the name of the equation
		dp.property("node_id", get(boost::vertex_index, graph)); // this is needed
		std::ofstream outf("graph.dot");
		boost::write_graphviz_dp(outf, graph, dp);
	}

	// calculate strong connected components and store them in 'component'
	std::vector<int> component(boost::num_vertices(graph));
	boost::strong_components(graph,&component[0]);

	// group neccessary equations together
	int num_comp = *std::max_element(component.begin(), component.end()) + 1; // find the number of components
	std::vector<std::vector<std::pair<VarPtr,Polynomial<SR>>>> grouped_equations;
	grouped_equations.resize(num_comp);

	// iterate over all vertices (0 to n)
	// collect the necessary variables + equations for every component
	for (unsigned int j = 0; j != component.size(); ++j)
	{
		//std::cout << j << ", " << graph[j].var << " is in component " << component[j] << std::endl;
		grouped_equations[component[j]].push_back(std::pair<VarPtr,Polynomial<SR>>(graph[j].var, graph[j].rex));
	}

	return grouped_equations;
}

// apply the newton method to the given input
template <typename SR>
std::map<VarPtr, SR> apply_newton(std::vector<std::pair<VarPtr, Polynomial<SR>>> equations, bool scc, bool iteration_flag, int iterations, bool graphviz_output)
{
	// TODO: sanity checks on the input!

	// generate an instance of the newton solver
	Newton<SR> newton;

	// if we use the scc method, group the equations
	// the outer vector contains SCCs starting with a bottom SCC at 0
	std::vector<std::vector<std::pair<VarPtr,Polynomial<SR>>>> equations2;
	if(scc)
	{
		auto tmp = group_by_scc(equations, graphviz_output);
		equations2.insert(equations2.begin(), tmp.begin(), tmp.end());
	}
	else if (!scc)
	{
		equations2.push_back(equations);
	}

	// this holds the solution
	std::map<VarPtr, SR> solution;

	// the same loop is used for both the scc and the non-scc variant
	// in the non-scc variant, we just run once through the loop
	//for(auto it1 = equations2.begin(); it != equations2.end(); ++it)
	for(unsigned int j = 0; j != equations2.size(); ++j)
	{
		// use the solutions to get rid of variables in the remaining equations
		// does nothing in the first round
		std::vector<std::pair<VarPtr, Polynomial<SR>>> tmp1;
		for(auto it = equations2[j].begin(); it != equations2[j].end(); ++it)
		{ // it = (VarPtr, Polynomial[SR])
			auto tmp2 = it->second.partial_eval(solution);
			tmp1.push_back(std::pair<VarPtr, Polynomial<SR>>(it->first, tmp2));
		}
		// replace old equations with simplified ones
		equations2[j] = tmp1;

		// dynamic iterations
		if(!iteration_flag)
			// for commutative SRs newton has converged after n+1 iterations, so use this number as default
			iterations = equations2[j].size() + 1;

		// do some real work here
		std::map<VarPtr, SR> result = newton.solve_fixpoint(equations2[j], iterations);

		// copy the results into the solution map
		solution.insert(result.begin(), result.end());
	}

	return solution;
}

template <typename SR>
std::string result_string(std::map<VarPtr,SR> result)
{
	std::stringstream ss;
	for(auto r_it = result.begin(); r_it != result.end(); ++r_it)
		ss << r_it->first << " == " << r_it->second << std::endl;
	return ss.str();
}

int main(int argc, char* argv[])
{
	namespace po = boost::program_options;

	po::options_description desc("Allowed options");
	desc.add_options()
		( "scc", "apply newton method iteratively to strongly connected components of the equation graph" )
		( "help,h", "print this help message" )
		( "iterations,i", po::value<int>(), "specify the number of newton iterations. default is optimal number" )
		//( "verbose", "enable verbose output" )
		//( "debug", "enable debug output" )
		( "test", "just for testing purposes ... explicit test defined in main()" )
		( "file,f", po::value<std::string>(), "input file" )
		( "float", "float semiring" )
		( "rexp", "commutative regular expression semiring" )
		( "slset", "explicit semilinear sets semiring (as vectors)" )
		( "graphviz", "create the file graph.dot with the equation graph" )
		;

	po::variables_map vm;
	po::store(po::parse_command_line(argc, argv, desc), vm);
	po::notify(vm);

	if(vm.count("test")) {
		Newton<SemilinSetExp> newton;
		std::vector<VarPtr> variables;
		variables.push_back(Var::getVar("x"));
		std::cout << "- newton (cnt-SR):" << std::endl;

		std::vector<Polynomial<SemilinSetExp> > polynomials;
		Polynomial<SemilinSetExp> f1 = Polynomial<SemilinSetExp>({
		Monomial<SemilinSetExp>(SemilinSetExp(Var::getVar("a")), {Var::getVar("x"),Var::getVar("x")}),
		Monomial<SemilinSetExp>(SemilinSetExp(Var::getVar("c")), {}) });

		polynomials.push_back(f1);

		Matrix<SemilinSetExp> result = newton.solve_fixpoint(polynomials, variables, 2);
		std::cout << result << std::endl;

/*		auto s1 = CommutativeRExp(Var::getVar("a"));
		auto s2 = CommutativeRExp(Var::getVar("b"));
		auto m1 = Matrix<CommutativeRExp>(1,1,{s1});
		auto m2 = Matrix<CommutativeRExp>(1,1,{s2});
*/

		// this actually led to a strange bug with the ublas-matrix implementation!!
/*		auto s1 = SemilinSetExp(Var::getVar("a"));
		auto s2 = SemilinSetExp(Var::getVar("b"));
		auto m1 = Matrix<SemilinSetExp>(1,1,{s1});
		auto m2 = Matrix<SemilinSetExp>(1,1,{s2});

		auto m3 = m1*m2;
		std::cout << m3;
*/
		return 0;
	}

	if(vm.count("help"))
	{
		std::cout << desc << std::endl;
		return 0;
	}

	int iterations=0;
	if(vm.count("iterations"))
		iterations = vm["iterations"].as<int>();

	// check if we can do something useful
	if(!vm.count("float") && !vm.count("rexp") && !vm.count("slset")) // check for all compatible parameters
	{
		std::cout << "Please supply a supported semiring :)" << std::endl;
		return 0;
	}

	std::vector<std::string> input;
	std::string line;
	if(vm.count("file"))
	{
		// we are reading the input from the given file
		std::ifstream file;
		file.open(vm["file"].as<std::string>(), std::ifstream::in);
		while(std::getline(file, line))
			input.push_back(line);
	}
	else
	{
		// we are reading from stdin
		while(std::getline(std::cin, line))
			input.push_back(line);
	}

	// join the input into one string
	std::string input_all = std::accumulate(input.begin(), input.end(), std::string(""));

	Parser p;

	if(vm.count("slset")) {
		std::vector<std::pair<VarPtr, Polynomial<SemilinSetExp>>> equations(p.slset_parser(input_all));
		if(equations.empty()) return -1;

		for(auto eq_it = equations.begin(); eq_it != equations.end(); ++eq_it)
		{
			std::cout << "* " << eq_it->first << " → " << eq_it->second << std::endl;
		}

		auto result = apply_newton<SemilinSetExp>(equations, vm.count("scc"), vm.count("iterations"), iterations, vm.count("graphviz"));
		std::cout << result_string(result) << std::endl;
	}
	else if(vm.count("rexp")) {
		// parse the input into a list of (Var → Polynomial[SR])
		std::vector<std::pair<VarPtr, Polynomial<CommutativeRExp>>> equations(p.rexp_parser(input_all));
		if(equations.empty()) return -1;

		for(auto eq_it = equations.begin(); eq_it != equations.end(); ++eq_it)
		{
			std::cout << "* " << eq_it->first << " → " << eq_it->second << std::endl;
		}

		// apply the newton method to the equations
		auto result = apply_newton<CommutativeRExp>(equations, vm.count("scc"), vm.count("iterations"), iterations, vm.count("graphviz"));
		std::cout << result_string(result) << std::endl;
	}
	else if(vm.count("float")) {
		std::vector<std::pair<VarPtr, Polynomial<FloatSemiring>>> equations(p.float_parser(input_all));
		if(equations.empty()) return -1;

		for(auto eq_it = equations.begin(); eq_it != equations.end(); ++eq_it)
		{
			std::cout << "* " << eq_it->first << " → " << eq_it->second << std::endl;
		}

		auto result = apply_newton<FloatSemiring>(equations, vm.count("scc"), vm.count("iterations"), iterations, vm.count("graphviz"));
		std::cout << result_string(result) << std::endl;
	}

	return 0;
}
<|endoftext|>


<commit_before>/*
 * DISTRHO Plugin Framework (DPF)
 * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
 *
 * Permission to use, copy, modify, and/or distribute this software for any purpose with
 * or without fee is hereby granted, provided that the above copyright notice and this
 * permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef DISTRHO_UI_HPP_INCLUDED
#define DISTRHO_UI_HPP_INCLUDED

#include "extra/LeakDetector.hpp"
#include "src/DistrhoPluginChecks.h"

#ifdef DGL_CAIRO
# include "Cairo.hpp"
#endif
#ifdef DGL_OPENGL
# include "OpenGL.hpp"
#endif
#ifdef DGL_VULKAN
# include "Vulkan.hpp"
#endif

#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
# include "../dgl/Base.hpp"
# include "extra/ExternalWindow.hpp"
typedef DISTRHO_NAMESPACE::ExternalWindow UIWidget;
#elif DISTRHO_UI_USE_CUSTOM
# include DISTRHO_UI_CUSTOM_INCLUDE_PATH
typedef DISTRHO_UI_CUSTOM_WIDGET_TYPE UIWidget;
#elif DISTRHO_UI_USE_CAIRO
# include "../dgl/Cairo.hpp"
typedef DGL_NAMESPACE::CairoTopLevelWidget UIWidget;
#elif DISTRHO_UI_USE_NANOVG
# include "../dgl/NanoVG.hpp"
typedef DGL_NAMESPACE::NanoTopLevelWidget UIWidget;
#else
# include "../dgl/TopLevelWidget.hpp"
typedef DGL_NAMESPACE::TopLevelWidget UIWidget;
#endif

START_NAMESPACE_DISTRHO

/* ------------------------------------------------------------------------------------------------------------
 * DPF UI */

/**
   @addtogroup MainClasses
   @{
 */

/**
   DPF UI class from where UI instances are created.

   @note You must call setSize during construction,
   @TODO Detailed information about this class.
 */
class UI : public UIWidget
{
public:
   /**
      UI class constructor.
      The UI should be initialized to a default state that matches the plugin side.
    */
    UI(uint width = 0, uint height = 0);

   /**
      Destructor.
    */
    virtual ~UI();

   /* --------------------------------------------------------------------------------------------------------
    * Host state */

   /**
      Get the color used for UI background (i.e. window color) in RGBA format.
      Returns 0 by default, in case of error or lack of host support.

      The following example code can be use to extract individual colors:
      ```
      const int red   = (bgColor >> 24) & 0xff;
      const int green = (bgColor >> 16) & 0xff;
      const int blue  = (bgColor >>  8) & 0xff;
      ```
    */
    uint getBackgroundColor() const noexcept;

   /**
      Get the color used for UI foreground (i.e. text color) in RGBA format.
      Returns 0xffffffff by default, in case of error or lack of host support.

      The following example code can be use to extract individual colors:
      ```
      const int red   = (fgColor >> 24) & 0xff;
      const int green = (fgColor >> 16) & 0xff;
      const int blue  = (fgColor >>  8) & 0xff;
      ```
    */
    uint getForegroundColor() const noexcept;

   /**
      Get the current sample rate used in plugin processing.
      @see sampleRateChanged(double)
    */
    double getSampleRate() const noexcept;

   /**
      editParameter.

      Touch/pressed-down event.
      Lets the host know the user is tweaking a parameter.
      Required in some hosts to record automation.
    */
    void editParameter(uint32_t index, bool started);

   /**
      setParameterValue.

      Change a parameter value in the Plugin.
    */
    void setParameterValue(uint32_t index, float value);

#if DISTRHO_PLUGIN_WANT_STATE
   /**
      setState.
      @TODO Document this.
    */
    void setState(const char* key, const char* value);
#endif

#if DISTRHO_PLUGIN_WANT_STATEFILES
   /**
      Request a new file from the host, matching the properties of a state key.@n
      This will use the native host file browser if available, otherwise a DPF built-in file browser is used.@n
      Response will be sent asynchronously to stateChanged, with the matching key and the new file as the value.@n
      It is not possible to know if the action was cancelled by the user.

      @return Success if a file-browser was opened, otherwise false.
      @note You cannot request more than one file at a time.
    */
    bool requestStateFile(const char* key);
#endif

#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
   /**
      sendNote.
      @TODO Document this.
      @note Work in progress. Implemented for DSSI and LV2 formats.
    */
    void sendNote(uint8_t channel, uint8_t note, uint8_t velocity);
#endif

#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
   /* --------------------------------------------------------------------------------------------------------
    * Direct DSP access - DO NOT USE THIS UNLESS STRICTLY NECESSARY!! */

   /**
      getPluginInstancePointer.
      @TODO Document this.
    */
    void* getPluginInstancePointer() const noexcept;
#endif

#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
   /* --------------------------------------------------------------------------------------------------------
    * External UI helpers */

   /**
      Get the bundle path that will be used for the next UI.
      @note: This function is only valid during createUI(),
             it will return null when called from anywhere else.
    */
    static const char* getNextBundlePath() noexcept;

   /**
      Get the scale factor that will be used for the next UI.
      @note: This function is only valid during createUI(),
             it will return 1.0 when called from anywhere else.
    */
    static double getNextScaleFactor() noexcept;

# if DISTRHO_PLUGIN_HAS_EMBED_UI
   /**
      Get the Window Id that will be used for the next created window.
      @note: This function is only valid during createUI(),
             it will return 0 when called from anywhere else.
    */
    static uintptr_t getNextWindowId() noexcept;
# endif
#endif

protected:
   /* --------------------------------------------------------------------------------------------------------
    * DSP/Plugin Callbacks */

   /**
      A parameter has changed on the plugin side.@n
      This is called by the host to inform the UI about parameter changes.
    */
    virtual void parameterChanged(uint32_t index, float value) = 0;

#if DISTRHO_PLUGIN_WANT_PROGRAMS
   /**
      A program has been loaded on the plugin side.@n
      This is called by the host to inform the UI about program changes.
    */
    virtual void programLoaded(uint32_t index) = 0;
#endif

#if DISTRHO_PLUGIN_WANT_STATE
   /**
      A state has changed on the plugin side.@n
      This is called by the host to inform the UI about state changes.
    */
    virtual void stateChanged(const char* key, const char* value) = 0;
#endif

   /* --------------------------------------------------------------------------------------------------------
    * DSP/Plugin Callbacks (optional) */

   /**
      Optional callback to inform the UI about a sample rate change on the plugin side.
      @see getSampleRate()
    */
    virtual void sampleRateChanged(double newSampleRate);

#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
   /* --------------------------------------------------------------------------------------------------------
    * UI Callbacks (optional) */

   /**
      uiIdle.
      @TODO Document this.
    */
    virtual void uiIdle() {}

# ifndef DGL_FILE_BROWSER_DISABLED
   /**
      File browser selected function.
      @see Window::onFileSelected(const char*)
    */
    virtual void uiFileBrowserSelected(const char* filename);
# endif

   /**
      OpenGL window reshape function, called when parent window is resized.
      You can reimplement this function for a custom OpenGL state.
      @see Window::onReshape(uint,uint)
    */
    virtual void uiReshape(uint width, uint height);

   /* --------------------------------------------------------------------------------------------------------
    * UI Resize Handling, internal */

   /**
      OpenGL widget resize function, called when the widget is resized.
      This is overriden here so the host knows when the UI is resized by you.
      @see Widget::onResize(const ResizeEvent&)
    */
    void onResize(const ResizeEvent& ev) override;
#endif

    // -------------------------------------------------------------------------------------------------------

private:
    struct PrivateData;
    PrivateData* const uiData;
    friend class UIExporter;
    friend class UIExporterWindow;

    DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UI)
};

/** @} */

/* ------------------------------------------------------------------------------------------------------------
 * Create UI, entry point */

/**
   @addtogroup EntryPoints
   @{
 */

/**
   createUI.
   @TODO Document this.
 */
extern UI* createUI();

/** @} */

// -----------------------------------------------------------------------------------------------------------

END_NAMESPACE_DISTRHO

#endif // DISTRHO_UI_HPP_INCLUDED
<commit_msg>Document sendNote, remove note about incomplete implementation<commit_after>/*
 * DISTRHO Plugin Framework (DPF)
 * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
 *
 * Permission to use, copy, modify, and/or distribute this software for any purpose with
 * or without fee is hereby granted, provided that the above copyright notice and this
 * permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef DISTRHO_UI_HPP_INCLUDED
#define DISTRHO_UI_HPP_INCLUDED

#include "extra/LeakDetector.hpp"
#include "src/DistrhoPluginChecks.h"

#ifdef DGL_CAIRO
# include "Cairo.hpp"
#endif
#ifdef DGL_OPENGL
# include "OpenGL.hpp"
#endif
#ifdef DGL_VULKAN
# include "Vulkan.hpp"
#endif

#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
# include "../dgl/Base.hpp"
# include "extra/ExternalWindow.hpp"
typedef DISTRHO_NAMESPACE::ExternalWindow UIWidget;
#elif DISTRHO_UI_USE_CUSTOM
# include DISTRHO_UI_CUSTOM_INCLUDE_PATH
typedef DISTRHO_UI_CUSTOM_WIDGET_TYPE UIWidget;
#elif DISTRHO_UI_USE_CAIRO
# include "../dgl/Cairo.hpp"
typedef DGL_NAMESPACE::CairoTopLevelWidget UIWidget;
#elif DISTRHO_UI_USE_NANOVG
# include "../dgl/NanoVG.hpp"
typedef DGL_NAMESPACE::NanoTopLevelWidget UIWidget;
#else
# include "../dgl/TopLevelWidget.hpp"
typedef DGL_NAMESPACE::TopLevelWidget UIWidget;
#endif

START_NAMESPACE_DISTRHO

/* ------------------------------------------------------------------------------------------------------------
 * DPF UI */

/**
   @addtogroup MainClasses
   @{
 */

/**
   DPF UI class from where UI instances are created.

   @note You must call setSize during construction,
   @TODO Detailed information about this class.
 */
class UI : public UIWidget
{
public:
   /**
      UI class constructor.
      The UI should be initialized to a default state that matches the plugin side.
    */
    UI(uint width = 0, uint height = 0);

   /**
      Destructor.
    */
    virtual ~UI();

   /* --------------------------------------------------------------------------------------------------------
    * Host state */

   /**
      Get the color used for UI background (i.e. window color) in RGBA format.
      Returns 0 by default, in case of error or lack of host support.

      The following example code can be use to extract individual colors:
      ```
      const int red   = (bgColor >> 24) & 0xff;
      const int green = (bgColor >> 16) & 0xff;
      const int blue  = (bgColor >>  8) & 0xff;
      ```
    */
    uint getBackgroundColor() const noexcept;

   /**
      Get the color used for UI foreground (i.e. text color) in RGBA format.
      Returns 0xffffffff by default, in case of error or lack of host support.

      The following example code can be use to extract individual colors:
      ```
      const int red   = (fgColor >> 24) & 0xff;
      const int green = (fgColor >> 16) & 0xff;
      const int blue  = (fgColor >>  8) & 0xff;
      ```
    */
    uint getForegroundColor() const noexcept;

   /**
      Get the current sample rate used in plugin processing.
      @see sampleRateChanged(double)
    */
    double getSampleRate() const noexcept;

   /**
      editParameter.

      Touch/pressed-down event.
      Lets the host know the user is tweaking a parameter.
      Required in some hosts to record automation.
    */
    void editParameter(uint32_t index, bool started);

   /**
      setParameterValue.

      Change a parameter value in the Plugin.
    */
    void setParameterValue(uint32_t index, float value);

#if DISTRHO_PLUGIN_WANT_STATE
   /**
      setState.
      @TODO Document this.
    */
    void setState(const char* key, const char* value);
#endif

#if DISTRHO_PLUGIN_WANT_STATEFILES
   /**
      Request a new file from the host, matching the properties of a state key.@n
      This will use the native host file browser if available, otherwise a DPF built-in file browser is used.@n
      Response will be sent asynchronously to stateChanged, with the matching key and the new file as the value.@n
      It is not possible to know if the action was cancelled by the user.

      @return Success if a file-browser was opened, otherwise false.
      @note You cannot request more than one file at a time.
    */
    bool requestStateFile(const char* key);
#endif

#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
   /**
      Send a single MIDI note from the UI to the plugin DSP side.@n
      A note with zero velocity will be sent as note-off (MIDI 0x80), otherwise note-on (MIDI 0x90).
    */
    void sendNote(uint8_t channel, uint8_t note, uint8_t velocity);
#endif

#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
   /* --------------------------------------------------------------------------------------------------------
    * Direct DSP access - DO NOT USE THIS UNLESS STRICTLY NECESSARY!! */

   /**
      getPluginInstancePointer.
      @TODO Document this.
    */
    void* getPluginInstancePointer() const noexcept;
#endif

#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
   /* --------------------------------------------------------------------------------------------------------
    * External UI helpers */

   /**
      Get the bundle path that will be used for the next UI.
      @note: This function is only valid during createUI(),
             it will return null when called from anywhere else.
    */
    static const char* getNextBundlePath() noexcept;

   /**
      Get the scale factor that will be used for the next UI.
      @note: This function is only valid during createUI(),
             it will return 1.0 when called from anywhere else.
    */
    static double getNextScaleFactor() noexcept;

# if DISTRHO_PLUGIN_HAS_EMBED_UI
   /**
      Get the Window Id that will be used for the next created window.
      @note: This function is only valid during createUI(),
             it will return 0 when called from anywhere else.
    */
    static uintptr_t getNextWindowId() noexcept;
# endif
#endif

protected:
   /* --------------------------------------------------------------------------------------------------------
    * DSP/Plugin Callbacks */

   /**
      A parameter has changed on the plugin side.@n
      This is called by the host to inform the UI about parameter changes.
    */
    virtual void parameterChanged(uint32_t index, float value) = 0;

#if DISTRHO_PLUGIN_WANT_PROGRAMS
   /**
      A program has been loaded on the plugin side.@n
      This is called by the host to inform the UI about program changes.
    */
    virtual void programLoaded(uint32_t index) = 0;
#endif

#if DISTRHO_PLUGIN_WANT_STATE
   /**
      A state has changed on the plugin side.@n
      This is called by the host to inform the UI about state changes.
    */
    virtual void stateChanged(const char* key, const char* value) = 0;
#endif

   /* --------------------------------------------------------------------------------------------------------
    * DSP/Plugin Callbacks (optional) */

   /**
      Optional callback to inform the UI about a sample rate change on the plugin side.
      @see getSampleRate()
    */
    virtual void sampleRateChanged(double newSampleRate);

#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
   /* --------------------------------------------------------------------------------------------------------
    * UI Callbacks (optional) */

   /**
      uiIdle.
      @TODO Document this.
    */
    virtual void uiIdle() {}

# ifndef DGL_FILE_BROWSER_DISABLED
   /**
      File browser selected function.
      @see Window::onFileSelected(const char*)
    */
    virtual void uiFileBrowserSelected(const char* filename);
# endif

   /**
      OpenGL window reshape function, called when parent window is resized.
      You can reimplement this function for a custom OpenGL state.
      @see Window::onReshape(uint,uint)
    */
    virtual void uiReshape(uint width, uint height);

   /* --------------------------------------------------------------------------------------------------------
    * UI Resize Handling, internal */

   /**
      OpenGL widget resize function, called when the widget is resized.
      This is overriden here so the host knows when the UI is resized by you.
      @see Widget::onResize(const ResizeEvent&)
    */
    void onResize(const ResizeEvent& ev) override;
#endif

    // -------------------------------------------------------------------------------------------------------

private:
    struct PrivateData;
    PrivateData* const uiData;
    friend class UIExporter;
    friend class UIExporterWindow;

    DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UI)
};

/** @} */

/* ------------------------------------------------------------------------------------------------------------
 * Create UI, entry point */

/**
   @addtogroup EntryPoints
   @{
 */

/**
   createUI.
   @TODO Document this.
 */
extern UI* createUI();

/** @} */

// -----------------------------------------------------------------------------------------------------------

END_NAMESPACE_DISTRHO

#endif // DISTRHO_UI_HPP_INCLUDED
<|endoftext|>


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

#include <bsls_ident.h>
BSLS_IDENT_RCSID(bdldfp_decimalconvertutil_cpp,"$Id$ $CSID$")

#include <bdldfp_decimalplatform.h>

#include <bsls_assert.h>

#ifdef BDLDFP_DECIMALPLATFORM_C99_TR
#  ifndef  __STDC_WANT_DEC_FP__
#    error __STDC_WANT_DEC_FP__ must be defined on the command line!
     char die[-42];     // if '#error' unsupported
#  endif
#endif

#include <math.h>

#include <bsl_cstring.h>

#include <bsl_algorithm.h>
#include <bsl_iostream.h>  // TODO TBD - remove this, it is just for debugging

namespace BloombergLP {
namespace bdldfp {

namespace {
                        // Reverse Memory

static void memrev(void *buffer, size_t count)
    // Reverse the order of the first specified 'count' bytes, at the beginning
    // of the specified 'buffer'.  'count % 2' must be zero.
{
    unsigned char *b = static_cast<unsigned char *>(buffer);
    bsl::reverse(b, b + count);
}

                        // Mem copy with reversal functions

unsigned char *memReverseIfNeeded(void *buffer, size_t count)
    // Reverse the first specified 'count' bytes from the specified 'buffer`,
    // if the host endian is different from network endian, and return the
    // address computed from 'static_cast<unsigned char *>(buffer) + count'.
{
#ifdef BDLDFP_DECIMALPLATFORM_LITTLE_ENDIAN
    // little endian, needs to do some byte juggling
    memrev(buffer, count);
#endif
    return static_cast<unsigned char*>(buffer) + count;
}

                        // Decimal-network conversion functions

template <class DECIMAL_TYPE>
const unsigned char *decimalFromNetworkT(DECIMAL_TYPE        *decimal,
                                         const unsigned char *buffer)
    // Construct into the specified 'decimal', the base-10 value represented by
    // the network-ordered bytes in the specified 'buffer', and return a raw
    // memory pointer, providing modifiable access, to one byte past the last
    // byte read from 'buffer'.
{
    bsl::memcpy(decimal, buffer, sizeof(DECIMAL_TYPE));
    memReverseIfNeeded(decimal, sizeof(DECIMAL_TYPE));

    DecimalConvertUtil::decimalFromDPD(
                                   decimal,
                                   reinterpret_cast<unsigned char *>(decimal));

    return buffer + sizeof(DECIMAL_TYPE);
}

template <class DECIMAL_TYPE>
unsigned char *decimalToNetworkT(unsigned char *buffer, DECIMAL_TYPE decimal)
    // Construct into the specified 'buffer', the network-ordered byte
    // representation of the base-10 value of the specified 'decimal', and,
    // return a raw memory pointer, providing modifiable access, to one byte
    // past the last written byte of the 'buffer'.
{
    DecimalConvertUtil::decimalToDPD(buffer, decimal);
    return memReverseIfNeeded(buffer, sizeof(DECIMAL_TYPE));
}

                        // =================
                        // class StdioFormat
                        // =================

template <typename> struct StdioFormat;
    // This 'struct' template provides a method, 'format', that returns a
    // 'printf'-style format string to format values of the template parameter
    // type that can be used to store a decimal value that was previously
    // converted to this type.

template <>
struct StdioFormat<float> {
    // This template specialization of 'StdioFormat' provides a function that
    // returns a 'printf'-style format string for 'float' values.

    static const char* format();
        // Return a 'printf'-style format string that can be used to restore a
        // decimal value that was previously converted to a 'float' value.
        // Refer to the documentation of 'decimalFromFloat' for the conversion
        // rules.
};

template <>
struct StdioFormat<double> {
    // This template specialization of 'StdioFormat' provides a function that
    // returns a 'printf'-style format string for 'double' values.

    static char const* format();
        // Return a 'printf'-style format string that can be used to restore a
        // decimal value that was previously converted to a 'double' value.
        // Refer to the documentation of 'decimalFromDouble' for the conversion
        // rules.
};

                        // -----------------
                        // class StdioFormat
                        // -----------------

const char* StdioFormat<float>::format()
{
    return "%.6g";
}

const char* StdioFormat<double>::format()
{
    return "%.15g";
}

                        // ===================
                        // class DecimalTraits
                        // ===================

template <typename> struct DecimalTraits;
    // This 'struct' template provides a way to make a decimal of the template
    // parameter type though a consistent interface.

template <>
struct DecimalTraits<Decimal32> {
    // This template specialization of 'DecimalTraits' provides utilities to
    // create 'Decimal32' values.

    typedef int SignificandType;
        // This 'typedef' defines a type that is large enough to hold the
        // significant of 'Decimal32'.

    static Decimal32 make(int significand, int exponent);
        // Return a 'Decimal32' value having the specified 'significand' and
        // the specified 'exponent'.
};

template <>
struct DecimalTraits<Decimal64> {
    // This template specialization of 'DecimalTraits' provides utilities to
    // create 'Decimal64' values.

    typedef long long SignificandType;
        // This 'typedef' defines a type that is large enough to hold the
        // significant of 'Decimal64'.

    static Decimal64 make(long long significand, int exponent);
        // Return a 'Decimal64' value having the specified 'significand' and
        // the specified 'exponent'.

};

template <>
struct DecimalTraits<bdldfp::Decimal128> {
    // This template specialization of 'DecimalTraits' provides utilities to
    // create 'Decimal128' values.

    typedef long long SignificandType;
        // This 'typedef' defines a type that is large enough to hold the
        // significant of 'Decimal128' if it's small enough to be convertible
        // to a double.

    static bdldfp::Decimal128 make(long long significand, int exponent);
        // Return a 'Decimal128' value having the specified 'significand' and
        // the specified 'exponent'.
};

                        // ===================
                        // class DecimalTraits
                        // ===================

Decimal32 DecimalTraits<Decimal32>::make(int significand, int exponent)
{
    return bdldfp::DecimalUtil::makeDecimalRaw32(significand, exponent);
}

Decimal64 DecimalTraits<Decimal64>::make(long long significand, int exponent)
{
    return bdldfp::DecimalUtil::makeDecimalRaw64(significand, exponent);
}

Decimal128 DecimalTraits<Decimal128>::make(long long significand, int exponent)
{
    return bdldfp::DecimalUtil::makeDecimalRaw128(significand, exponent);
}

                  // Helpers for Restoring Decimal from Binary

template <class DECIMAL_TYPE, class BINARY_TYPE>
void restoreDecimalFromBinary(DECIMAL_TYPE *dfp, BINARY_TYPE bfp)
    // Construct, in the specified 'dfp', a decimal floating point
    // representation of the value of the binary floating point value specified
    // by 'bfp'.
{

    if (bfp != bfp) {
        *dfp = bsl::numeric_limits<DECIMAL_TYPE>::quiet_NaN();
        if (bfp < 0) {
            *dfp = -*dfp;
        }
        return;                                                       // RETURN
    }

    if (bfp == bsl::numeric_limits<BINARY_TYPE>::infinity()) {
        *dfp = bsl::numeric_limits<DECIMAL_TYPE>::infinity();
        return;                                                       // RETURN
    }

    if (bfp == -bsl::numeric_limits<BINARY_TYPE>::infinity()) {
        *dfp = -bsl::numeric_limits<DECIMAL_TYPE>::infinity();
        return;                                                       // RETURN
    }

    char buffer[48];
    snprintf(buffer, sizeof(buffer), StdioFormat<BINARY_TYPE>::format(), bfp);

    typename DecimalTraits<DECIMAL_TYPE>::SignificandType significand(0);
    int  exponent(0);
    bool negative(false);

    char const* it(buffer);
    if (*it == '-') {
        negative = true;
        ++it;
    }
    for (; bsl::isdigit(static_cast<unsigned char>(*it)); ++it) {
        significand = significand * 10 + (*it - '0');
    }
    if (*it == '.') {
        ++it;
        for (; bsl::isdigit(static_cast<unsigned char>(*it)); ++it) {
            significand = significand * 10 + (*it - '0');
            --exponent;
        }
    }
    if (*it == 'e' || *it == 'E') {
        ++it;
        exponent += atoi(it);
    }

    *dfp = DecimalTraits<DECIMAL_TYPE>::make(significand, exponent);

    // Because the significand is a signed integer, it can not represent the
    // value -0, which distinct from +0 in decimal floating point. So instead
    // of converting the significand to a signed value, we change the decimal
    // value based on the sign appropriately after the decimal value is
    // created.

    if (negative) {
        *dfp = -(*dfp);
    }
}

}  // close unnamed namespace

                        // Network format converters

// Note that we do not use platform or bslsl supported converters because they
// work in terms of integers, so they would probably bleed out on the
// strict-aliasing rules.  We may solve that later on using the "union trick"
// and delegating to 'bsls_byteorder', but for now let's take it slow.

                        // Conversion to Network functions

unsigned char *DecimalConvertUtil::decimal32ToNetwork(unsigned char *buffer,
                                                      Decimal32      decimal)
{
    BSLS_ASSERT(buffer != 0);
    return decimalToNetworkT(buffer, decimal);
}

unsigned char *DecimalConvertUtil::decimal64ToNetwork(unsigned char *buffer,
                                                      Decimal64      decimal)
{
    BSLS_ASSERT(buffer != 0);
    return decimalToNetworkT(buffer, decimal);
}

unsigned char *DecimalConvertUtil::decimal128ToNetwork(unsigned char *buffer,
                                                       Decimal128     decimal)
{
    BSLS_ASSERT(buffer != 0);
    return decimalToNetworkT(buffer, decimal);
}

unsigned char *DecimalConvertUtil::decimalToNetwork(unsigned char *buffer,
                                                    Decimal32      decimal)
{
    BSLS_ASSERT(buffer != 0);
    return decimalToNetworkT(buffer, decimal);
}

unsigned char *DecimalConvertUtil::decimalToNetwork(unsigned char *buffer,
                                                    Decimal64      decimal)
{
    BSLS_ASSERT(buffer != 0);
    return decimalToNetworkT(buffer, decimal);
}

unsigned char *DecimalConvertUtil::decimalToNetwork(unsigned char *buffer,
                                                    Decimal128     decimal)
{
    BSLS_ASSERT(buffer != 0);
    return decimalToNetworkT(buffer, decimal);
}

                        // Conversion to Network functions

const unsigned char *DecimalConvertUtil::decimal32FromNetwork(
                                                  Decimal32           *decimal,
                                                  const unsigned char *buffer)
{
    BSLS_ASSERT(decimal != 0);
    return decimalFromNetworkT(decimal, buffer);
}

const unsigned char *DecimalConvertUtil::decimal64FromNetwork(
                                                  Decimal64           *decimal,
                                                  const unsigned char *buffer)
{
    BSLS_ASSERT(decimal != 0);
    return decimalFromNetworkT(decimal, buffer);
}

const unsigned char *DecimalConvertUtil::decimal128FromNetwork(
                                                  Decimal128          *decimal,
                                                  const unsigned char *buffer)
{
    BSLS_ASSERT(decimal != 0);
    return decimalFromNetworkT(decimal, buffer);
}

const unsigned char *DecimalConvertUtil::decimalFromNetwork(
                                                  Decimal32           *decimal,
                                                  const unsigned char *buffer)
{
    BSLS_ASSERT(decimal != 0);
    return decimalFromNetworkT(decimal, buffer);
}

const unsigned char *DecimalConvertUtil::decimalFromNetwork(
                                                  Decimal64           *decimal,
                                                  const unsigned char *buffer)
{
    BSLS_ASSERT(decimal != 0);
    return decimalFromNetworkT(decimal, buffer);
}

const unsigned char *DecimalConvertUtil::decimalFromNetwork(
                                                  Decimal128          *decimal,
                                                  const unsigned char *buffer)
{
    BSLS_ASSERT(decimal != 0);
    return decimalFromNetworkT(decimal, buffer);
}

            // Restore a Decimal Floating-Point from a Binary

                        // DecimalFromDouble functions

Decimal32 DecimalConvertUtil::decimal32FromDouble(double binary)
{
    Decimal32 rv;
    restoreDecimalFromBinary(&rv, binary);
    return rv;
}
Decimal64 DecimalConvertUtil::decimal64FromDouble(double binary)
{
    Decimal64 rv;
    restoreDecimalFromBinary(&rv, binary);
    return rv;
}
Decimal128 DecimalConvertUtil::decimal128FromDouble(double binary)
{
    Decimal128 rv;
    restoreDecimalFromBinary(&rv, binary);
    return rv;
}

                        // DecimalFromFloat functions

Decimal32 DecimalConvertUtil::decimal32FromFloat(float binary)
{
    Decimal32 rv;
    restoreDecimalFromBinary(&rv, binary);
    return rv;
}
Decimal64 DecimalConvertUtil::decimal64FromFloat(float binary)
{
    Decimal64 rv;
    restoreDecimalFromBinary(&rv, binary);
    return rv;
}
Decimal128 DecimalConvertUtil::decimal128FromFloat(float binary)
{
    Decimal128 rv;
    restoreDecimalFromBinary(&rv, binary);
    return rv;
}

}  // close package namespace
}  // close enterprise namespace

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

#include <bsls_ident.h>
BSLS_IDENT_RCSID(bdldfp_decimalconvertutil_cpp,"$Id$ $CSID$")

#include <bdldfp_decimalplatform.h>

#include <bsls_assert.h>

#ifdef BDLDFP_DECIMALPLATFORM_C99_TR
#  ifndef  __STDC_WANT_DEC_FP__
#    error __STDC_WANT_DEC_FP__ must be defined on the command line!
     char die[-42];     // if '#error' unsupported
#  endif
#endif

#include <bsl_algorithm.h>
#include <bsl_cstdlib.h>
#include <bsl_cstring.h>

namespace BloombergLP {
namespace bdldfp {

namespace {
                        // Reverse Memory

static void memrev(void *buffer, size_t count)
    // Reverse the order of the first specified 'count' bytes, at the beginning
    // of the specified 'buffer'.  'count % 2' must be zero.
{
    unsigned char *b = static_cast<unsigned char *>(buffer);
    bsl::reverse(b, b + count);
}

                        // Mem copy with reversal functions

unsigned char *memReverseIfNeeded(void *buffer, size_t count)
    // Reverse the first specified 'count' bytes from the specified 'buffer`,
    // if the host endian is different from network endian, and return the
    // address computed from 'static_cast<unsigned char *>(buffer) + count'.
{
#ifdef BDLDFP_DECIMALPLATFORM_LITTLE_ENDIAN
    // little endian, needs to do some byte juggling
    memrev(buffer, count);
#endif
    return static_cast<unsigned char*>(buffer) + count;
}

                        // Decimal-network conversion functions

template <class DECIMAL_TYPE>
const unsigned char *decimalFromNetworkT(DECIMAL_TYPE        *decimal,
                                         const unsigned char *buffer)
    // Construct into the specified 'decimal', the base-10 value represented by
    // the network-ordered bytes in the specified 'buffer', and return a raw
    // memory pointer, providing modifiable access, to one byte past the last
    // byte read from 'buffer'.
{
    bsl::memcpy(decimal, buffer, sizeof(DECIMAL_TYPE));
    memReverseIfNeeded(decimal, sizeof(DECIMAL_TYPE));

    DecimalConvertUtil::decimalFromDPD(
                                   decimal,
                                   reinterpret_cast<unsigned char *>(decimal));

    return buffer + sizeof(DECIMAL_TYPE);
}

template <class DECIMAL_TYPE>
unsigned char *decimalToNetworkT(unsigned char *buffer, DECIMAL_TYPE decimal)
    // Construct into the specified 'buffer', the network-ordered byte
    // representation of the base-10 value of the specified 'decimal', and,
    // return a raw memory pointer, providing modifiable access, to one byte
    // past the last written byte of the 'buffer'.
{
    DecimalConvertUtil::decimalToDPD(buffer, decimal);
    return memReverseIfNeeded(buffer, sizeof(DECIMAL_TYPE));
}

                        // =================
                        // class StdioFormat
                        // =================

template <typename> struct StdioFormat;
    // This 'struct' template provides a method, 'format', that returns a
    // 'printf'-style format string to format values of the template parameter
    // type that can be used to store a decimal value that was previously
    // converted to this type.

template <>
struct StdioFormat<float> {
    // This template specialization of 'StdioFormat' provides a function that
    // returns a 'printf'-style format string for 'float' values.

    static const char* format();
        // Return a 'printf'-style format string that can be used to restore a
        // decimal value that was previously converted to a 'float' value.
        // Refer to the documentation of 'decimalFromFloat' for the conversion
        // rules.
};

template <>
struct StdioFormat<double> {
    // This template specialization of 'StdioFormat' provides a function that
    // returns a 'printf'-style format string for 'double' values.

    static char const* format();
        // Return a 'printf'-style format string that can be used to restore a
        // decimal value that was previously converted to a 'double' value.
        // Refer to the documentation of 'decimalFromDouble' for the conversion
        // rules.
};

                        // -----------------
                        // class StdioFormat
                        // -----------------

const char* StdioFormat<float>::format()
{
    return "%.6g";
}

const char* StdioFormat<double>::format()
{
    return "%.15g";
}

                        // ===================
                        // class DecimalTraits
                        // ===================

template <typename> struct DecimalTraits;
    // This 'struct' template provides a way to make a decimal of the template
    // parameter type though a consistent interface.

template <>
struct DecimalTraits<Decimal32> {
    // This template specialization of 'DecimalTraits' provides utilities to
    // create 'Decimal32' values.

    typedef int SignificandType;
        // This 'typedef' defines a type that is large enough to hold the
        // significant of 'Decimal32'.

    static Decimal32 make(int significand, int exponent);
        // Return a 'Decimal32' value having the specified 'significand' and
        // the specified 'exponent'.
};

template <>
struct DecimalTraits<Decimal64> {
    // This template specialization of 'DecimalTraits' provides utilities to
    // create 'Decimal64' values.

    typedef long long SignificandType;
        // This 'typedef' defines a type that is large enough to hold the
        // significant of 'Decimal64'.

    static Decimal64 make(long long significand, int exponent);
        // Return a 'Decimal64' value having the specified 'significand' and
        // the specified 'exponent'.

};

template <>
struct DecimalTraits<bdldfp::Decimal128> {
    // This template specialization of 'DecimalTraits' provides utilities to
    // create 'Decimal128' values.

    typedef long long SignificandType;
        // This 'typedef' defines a type that is large enough to hold the
        // significant of 'Decimal128' if it's small enough to be convertible
        // to a double.

    static bdldfp::Decimal128 make(long long significand, int exponent);
        // Return a 'Decimal128' value having the specified 'significand' and
        // the specified 'exponent'.
};

                        // ===================
                        // class DecimalTraits
                        // ===================

Decimal32 DecimalTraits<Decimal32>::make(int significand, int exponent)
{
    return bdldfp::DecimalUtil::makeDecimalRaw32(significand, exponent);
}

Decimal64 DecimalTraits<Decimal64>::make(long long significand, int exponent)
{
    return bdldfp::DecimalUtil::makeDecimalRaw64(significand, exponent);
}

Decimal128 DecimalTraits<Decimal128>::make(long long significand, int exponent)
{
    return bdldfp::DecimalUtil::makeDecimalRaw128(significand, exponent);
}

                  // Helpers for Restoring Decimal from Binary

template <class DECIMAL_TYPE, class BINARY_TYPE>
void restoreDecimalFromBinary(DECIMAL_TYPE *dfp, BINARY_TYPE bfp)
    // Construct, in the specified 'dfp', a decimal floating point
    // representation of the value of the binary floating point value specified
    // by 'bfp'.
{

    if (bfp != bfp) {
        *dfp = bsl::numeric_limits<DECIMAL_TYPE>::quiet_NaN();
        if (bfp < 0) {
            *dfp = -*dfp;
        }
        return;                                                       // RETURN
    }

    if (bfp == bsl::numeric_limits<BINARY_TYPE>::infinity()) {
        *dfp = bsl::numeric_limits<DECIMAL_TYPE>::infinity();
        return;                                                       // RETURN
    }

    if (bfp == -bsl::numeric_limits<BINARY_TYPE>::infinity()) {
        *dfp = -bsl::numeric_limits<DECIMAL_TYPE>::infinity();
        return;                                                       // RETURN
    }

    char buffer[48];
    snprintf(buffer, sizeof(buffer), StdioFormat<BINARY_TYPE>::format(), bfp);

    typename DecimalTraits<DECIMAL_TYPE>::SignificandType significand(0);
    int  exponent(0);
    bool negative(false);

    char const* it(buffer);
    if (*it == '-') {
        negative = true;
        ++it;
    }
    for (; bsl::isdigit(static_cast<unsigned char>(*it)); ++it) {
        significand = significand * 10 + (*it - '0');
    }
    if (*it == '.') {
        ++it;
        for (; bsl::isdigit(static_cast<unsigned char>(*it)); ++it) {
            significand = significand * 10 + (*it - '0');
            --exponent;
        }
    }
    if (*it == 'e' || *it == 'E') {
        ++it;
        exponent += bsl::atoi(it);
    }

    *dfp = DecimalTraits<DECIMAL_TYPE>::make(significand, exponent);

    // Because the significand is a signed integer, it can not represent the
    // value -0, which distinct from +0 in decimal floating point. So instead
    // of converting the significand to a signed value, we change the decimal
    // value based on the sign appropriately after the decimal value is
    // created.

    if (negative) {
        *dfp = -(*dfp);
    }
}

}  // close unnamed namespace

                        // Network format converters

// Note that we do not use platform or bslsl supported converters because they
// work in terms of integers, so they would probably bleed out on the
// strict-aliasing rules.  We may solve that later on using the "union trick"
// and delegating to 'bsls_byteorder', but for now let's take it slow.

                        // Conversion to Network functions

unsigned char *DecimalConvertUtil::decimal32ToNetwork(unsigned char *buffer,
                                                      Decimal32      decimal)
{
    BSLS_ASSERT(buffer != 0);
    return decimalToNetworkT(buffer, decimal);
}

unsigned char *DecimalConvertUtil::decimal64ToNetwork(unsigned char *buffer,
                                                      Decimal64      decimal)
{
    BSLS_ASSERT(buffer != 0);
    return decimalToNetworkT(buffer, decimal);
}

unsigned char *DecimalConvertUtil::decimal128ToNetwork(unsigned char *buffer,
                                                       Decimal128     decimal)
{
    BSLS_ASSERT(buffer != 0);
    return decimalToNetworkT(buffer, decimal);
}

unsigned char *DecimalConvertUtil::decimalToNetwork(unsigned char *buffer,
                                                    Decimal32      decimal)
{
    BSLS_ASSERT(buffer != 0);
    return decimalToNetworkT(buffer, decimal);
}

unsigned char *DecimalConvertUtil::decimalToNetwork(unsigned char *buffer,
                                                    Decimal64      decimal)
{
    BSLS_ASSERT(buffer != 0);
    return decimalToNetworkT(buffer, decimal);
}

unsigned char *DecimalConvertUtil::decimalToNetwork(unsigned char *buffer,
                                                    Decimal128     decimal)
{
    BSLS_ASSERT(buffer != 0);
    return decimalToNetworkT(buffer, decimal);
}

                        // Conversion to Network functions

const unsigned char *DecimalConvertUtil::decimal32FromNetwork(
                                                  Decimal32           *decimal,
                                                  const unsigned char *buffer)
{
    BSLS_ASSERT(decimal != 0);
    return decimalFromNetworkT(decimal, buffer);
}

const unsigned char *DecimalConvertUtil::decimal64FromNetwork(
                                                  Decimal64           *decimal,
                                                  const unsigned char *buffer)
{
    BSLS_ASSERT(decimal != 0);
    return decimalFromNetworkT(decimal, buffer);
}

const unsigned char *DecimalConvertUtil::decimal128FromNetwork(
                                                  Decimal128          *decimal,
                                                  const unsigned char *buffer)
{
    BSLS_ASSERT(decimal != 0);
    return decimalFromNetworkT(decimal, buffer);
}

const unsigned char *DecimalConvertUtil::decimalFromNetwork(
                                                  Decimal32           *decimal,
                                                  const unsigned char *buffer)
{
    BSLS_ASSERT(decimal != 0);
    return decimalFromNetworkT(decimal, buffer);
}

const unsigned char *DecimalConvertUtil::decimalFromNetwork(
                                                  Decimal64           *decimal,
                                                  const unsigned char *buffer)
{
    BSLS_ASSERT(decimal != 0);
    return decimalFromNetworkT(decimal, buffer);
}

const unsigned char *DecimalConvertUtil::decimalFromNetwork(
                                                  Decimal128          *decimal,
                                                  const unsigned char *buffer)
{
    BSLS_ASSERT(decimal != 0);
    return decimalFromNetworkT(decimal, buffer);
}

            // Restore a Decimal Floating-Point from a Binary

                        // DecimalFromDouble functions

Decimal32 DecimalConvertUtil::decimal32FromDouble(double binary)
{
    Decimal32 rv;
    restoreDecimalFromBinary(&rv, binary);
    return rv;
}
Decimal64 DecimalConvertUtil::decimal64FromDouble(double binary)
{
    Decimal64 rv;
    restoreDecimalFromBinary(&rv, binary);
    return rv;
}
Decimal128 DecimalConvertUtil::decimal128FromDouble(double binary)
{
    Decimal128 rv;
    restoreDecimalFromBinary(&rv, binary);
    return rv;
}

                        // DecimalFromFloat functions

Decimal32 DecimalConvertUtil::decimal32FromFloat(float binary)
{
    Decimal32 rv;
    restoreDecimalFromBinary(&rv, binary);
    return rv;
}
Decimal64 DecimalConvertUtil::decimal64FromFloat(float binary)
{
    Decimal64 rv;
    restoreDecimalFromBinary(&rv, binary);
    return rv;
}
Decimal128 DecimalConvertUtil::decimal128FromFloat(float binary)
{
    Decimal128 rv;
    restoreDecimalFromBinary(&rv, binary);
    return rv;
}

}  // close package namespace
}  // close enterprise namespace

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


<commit_before>// @(#)root/gui:$Id$

/*************************************************************************
 * Copyright (C) 1995-2015, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TGTextViewStream                                                     //
//                                                                      //
// A TGTextViewStream is a text viewer widget. It is a specialization   //
// of TGTextView and std::ostream, and it uses a TGTextViewStreamBuf,   //
// who inherits from std::streambuf, allowing to stream text directly   //
// to the text view in a cout-like fashion                              //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TGTextViewStream.h"
#include "TSystem.h"

ClassImp(TGTextViewStreamBuf)

//______________________________________________________________________________
TGTextViewStreamBuf::TGTextViewStreamBuf(TGTextView *textview) :
   fTextView(textview)
{
   // TGTextViewStreamBuf constructor.

   fInputbuffer.reserve(32);
   setg(&fInputbuffer[0], &fInputbuffer[0], &fInputbuffer[0]);
   setp(&fInputbuffer[0], &fInputbuffer[0]);
}

//______________________________________________________________________________
Int_t TGTextViewStreamBuf::overflow(Int_t c)
{
   // Method called to put a character into the controlled output sequence
   // without changing the current position.

   typedef std::char_traits<char> Tr;
   if (c == Tr::eof())
      return Tr::not_eof(c);
   if (c=='\n') {
      fLinebuffer.push_back('\0');
      fTextView->AddLineFast(&fLinebuffer[0]);
      fLinebuffer.clear();
      fTextView->ShowBottom();
      fTextView->Update();
      gSystem->ProcessEvents();
   } else {
      fLinebuffer.push_back(c);
   }
   return c;
}

//______________________________________________________________________________
TGTextViewostream::TGTextViewostream(const TGWindow* parent, UInt_t w,
                                     UInt_t h,Int_t id, UInt_t sboptions,
                                     Pixel_t back) :
   TGTextView(parent, w, h, id, sboptions, back), std::ostream(&fStreambuffer),
   fStreambuffer(this)
{
   // TGTextViewostream constructor.

}

//______________________________________________________________________________
TGTextViewostream::TGTextViewostream(const TGWindow *parent, UInt_t w,
                                     UInt_t h, TGText *text, Int_t id,
                                     UInt_t sboptions, ULong_t back):
   TGTextView(parent, w, h, text, id, sboptions, back),
   std::ostream(&fStreambuffer), fStreambuffer(this)
{
   // TGTextViewostream constructor.

}

//______________________________________________________________________________
TGTextViewostream::TGTextViewostream(const TGWindow *parent, UInt_t w,
                                     UInt_t h,const char *string, Int_t id,
                                     UInt_t sboptions, ULong_t back):
   TGTextView(parent, w, h, string, id, sboptions, back),
   std::ostream(&fStreambuffer), fStreambuffer(this)
{
   // TGTextViewostream constructor.

}

<commit_msg>Suppress warning C4355: 'this' : used in base member initializer list (with VS2010)<commit_after>// @(#)root/gui:$Id$

/*************************************************************************
 * Copyright (C) 1995-2015, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TGTextViewStream                                                     //
//                                                                      //
// A TGTextViewStream is a text viewer widget. It is a specialization   //
// of TGTextView and std::ostream, and it uses a TGTextViewStreamBuf,   //
// who inherits from std::streambuf, allowing to stream text directly   //
// to the text view in a cout-like fashion                              //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TGTextViewStream.h"
#include "TSystem.h"

ClassImp(TGTextViewStreamBuf)

#ifdef R__WIN32
#pragma warning( push )
#pragma warning( disable : 4355 )
#endif

//______________________________________________________________________________
TGTextViewStreamBuf::TGTextViewStreamBuf(TGTextView *textview) :
   fTextView(textview)
{
   // TGTextViewStreamBuf constructor.

   fInputbuffer.reserve(32);
   setg(&fInputbuffer[0], &fInputbuffer[0], &fInputbuffer[0]);
   setp(&fInputbuffer[0], &fInputbuffer[0]);
}

//______________________________________________________________________________
Int_t TGTextViewStreamBuf::overflow(Int_t c)
{
   // Method called to put a character into the controlled output sequence
   // without changing the current position.

   typedef std::char_traits<char> Tr;
   if (c == Tr::eof())
      return Tr::not_eof(c);
   if (c=='\n') {
      fLinebuffer.push_back('\0');
      fTextView->AddLineFast(&fLinebuffer[0]);
      fLinebuffer.clear();
      fTextView->ShowBottom();
      fTextView->Update();
      gSystem->ProcessEvents();
   } else {
      fLinebuffer.push_back(c);
   }
   return c;
}

//______________________________________________________________________________
TGTextViewostream::TGTextViewostream(const TGWindow* parent, UInt_t w,
                                     UInt_t h,Int_t id, UInt_t sboptions,
                                     Pixel_t back) :
   TGTextView(parent, w, h, id, sboptions, back), std::ostream(&fStreambuffer),
   fStreambuffer(this)
{
   // TGTextViewostream constructor.

}

//______________________________________________________________________________
TGTextViewostream::TGTextViewostream(const TGWindow *parent, UInt_t w,
                                     UInt_t h, TGText *text, Int_t id,
                                     UInt_t sboptions, ULong_t back):
   TGTextView(parent, w, h, text, id, sboptions, back),
   std::ostream(&fStreambuffer), fStreambuffer(this)
{
   // TGTextViewostream constructor.

}

//______________________________________________________________________________
TGTextViewostream::TGTextViewostream(const TGWindow *parent, UInt_t w,
                                     UInt_t h,const char *string, Int_t id,
                                     UInt_t sboptions, ULong_t back):
   TGTextView(parent, w, h, string, id, sboptions, back),
   std::ostream(&fStreambuffer), fStreambuffer(this)
{
   // TGTextViewostream constructor.

}

#ifdef R__WIN32
#pragma warning( pop )
#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: file_path_helper.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2003-03-26 16:46:02 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _OSL_FILE_PATH_HELPER_HXX_
#define _OSL_FILE_PATH_HELPER_HXX_

#ifndef _OSL_FILE_PATH_HELPER_H_
#include "file_path_helper.h"
#endif

#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

namespace osl
{

 /*******************************************
    systemPathRemoveSeparator
    Removes the last separator from the
    given system path if any and if the path
    is not the root path '/'

    @param  ppustrPath [inout] a system path
            if the path is not the root path
            and the last character is a
            path separator it will be cut off
               ppustrPath must not be NULL and
            must point to a valid rtl_uString

    @returns nothing

  ******************************************/

 inline void systemPathRemoveSeparator(/*inout*/ rtl::OUString& Path)
 {
     osl_systemPathRemoveSeparator(Path.pData);
 }

 /*******************************************
    systemPathEnsureSeparator
    Adds a trailing path separator to the
    given system path if not already there
    and if the path is not the root path '/'

      @param    pustrPath [inout] a system path
            if the path is not the root path
            '/' and has no trailing separator
            a separator will be added
            ppustrPath must not be NULL and
            must point to a valid rtl_uString

    @returns nothing

  ******************************************/

 inline void systemPathEnsureSeparator(/*inout*/ rtl::OUString& Path)
 {
     osl_systemPathEnsureSeparator(&Path.pData);
 }

 /*******************************************
    systemPathIsRelativePath
    Returns true if the given path is a
    relative path and so starts not with '/'

    @param  pustrPath [in] a system path
            pustrPath must not be NULL

    @returns sal_True if the given path
             doesn't start with a separator
             else sal_False will be returned

  ******************************************/

 inline bool systemPathIsRelativePath(const rtl::OUString& Path)
 {
    return osl_systemPathIsRelativePath(Path.pData);
 }

 /******************************************
    systemPathIsAbsolutePath
    Returns true if the given path is an
    absolute path and so starts with a '/'

    @param pustrPath [in] a system path
           pustrPath must not be NULL

    @returns sal_True if the given path
             start's with a separator else
             sal_False will be returned

  *****************************************/

 inline bool systemPathIsAbsolutePath(const rtl::OUString& Path)
 {
     return osl_systemPathIsAbsolutePath(Path.pData);
 }

 /******************************************
    systemPathMakeAbsolutePath
    Append a relative path to a base path

    @param  pustrBasePath [in] a system
            path that will be considered as
            base path
            pustrBasePath must not be NULL

    @param  pustrRelPath [in] a system path
            that will be considered as
            relative path
            pustrBasePath must not be NULL

    @param  ppustrAbsolutePath [out] the
            resulting path which is a
            concatination of the base and
            the relative path
            if base path is empty the
            resulting absolute path is the
            relative path
            if relative path is empty the
            resulting absolute path is the
            base path
            if base and relative path are
            empty the resulting absolute
            path is also empty
            ppustrAbsolutePath must not be
            NULL and *ppustrAbsolutePath
            must be 0 or point to a valid
            rtl_uString

  *****************************************/

 inline void systemPathMakeAbsolutePath(
     const rtl::OUString& BasePath,
    const rtl::OUString& RelPath,
    rtl::OUString&       AbsolutePath)
 {
    osl_systemPathMakeAbsolutePath(
        BasePath.pData, RelPath.pData, &AbsolutePath.pData);
 }

 /*****************************************
    systemPathGetParent
    Replaces the last occurrance of a path
    separator with '\0' and returns the
    position where the '/' was replaced

    @param  pustrPath [inout] a system
            path, the last separator of
            this path will be replaced by
            a '\0'
            if the path is the root path
            '/' or the path is considered
            as to have no parent, e.g.
            '/NoParent' or 'NoParent' or
            the path is empty no
            replacement will be made
            pustrPath must not be NULL

    @returns the position of the last path
             separator that was replaced
             or 0 if no replacement took
             place

  ****************************************/

 inline sal_Int32 systemPathGetParent(/*inout*/ rtl::OUString& Path)
 {
    return osl_systemPathGetParent(Path.pData);
 }

 /*****************************************
     systemPathGetFileOrLastDirectoryPart
    Returns the file or the directory part
    of the given path

    @param pustrPath [in] a system path,
           must not be NULL

    @param ppustrFileOrDirPart [out] on
           return receives the last part
           of the given directory or the
           file name
           if pustrPath is the root path
           '/' an empty string will be
           returned
           if pustrPath has a trailing
           '/' the last part before the
           '/' will be returned else
           the part after the last '/'
           will be returned

    @returns nothing

  ****************************************/

 inline void systemPathGetFileNameOrLastDirectoryPart(
     const rtl::OUString& Path,
    rtl::OUString&       FileNameOrLastDirPart)
 {
    osl_systemPathGetFileNameOrLastDirectoryPart(
        Path.pData, &FileNameOrLastDirPart.pData);
 }

 /********************************************
     systemPathIsHiddenFileOrDirectoryEntry
    Returns sal_True if the last part of
    given system path is not '.' or '..'
    alone and starts with a '.'

    @param pustrPath [in] a system path,
           must not be NULL

    @returns sal_True if the last part of
             the given system path starts
             with '.' or sal_False the last
             part is '.' or '..' alone or
             doesn't start with a dot

 *********************************************/

 inline bool systemPathIsHiddenFileOrDirectoryEntry(
     const rtl::OUString& Path)
 {
    return osl_systemPathIsHiddenFileOrDirectoryEntry(Path.pData);
 }

 /************************************************
     systemPathIsLocalOrParentDirectoryEntry
    Returns sal_True if the last part of the given
    system path is the local directory entry '.'
    or the parent directory entry '..'

    @param pustrPath [in] a system path,
           must not be NULL

    @returns sal_True if the last part of the
             given system path is '.' or '..'
             else sal_False

 ************************************************/

 inline bool systemPathIsLocalOrParentDirectoryEntry(
     const rtl::OUString& Path)
 {
    return osl_systemPathIsLocalOrParentDirectoryEntry(Path.pData);
 }

 /************************************************
  searchPath
  ***********************************************/

 inline bool searchPath(
     const rtl::OUString& ustrFilePath,
    const rtl::OUString& ustrSearchPathList,
    rtl::OUString& ustrPathFound)
 {
     return osl_searchPath(
        ustrFilePath.pData,
        ustrSearchPathList.pData,
        &ustrPathFound.pData);
 }

 } // namespace osl

 #endif /* #ifndef _OSL_PATH_HELPER_HXX_ */

<commit_msg>INTEGRATION: CWS ooo19126 (1.3.350); FILE MERGED 2005/09/05 17:44:25 rt 1.3.350.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: file_path_helper.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 14:55:55 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _OSL_FILE_PATH_HELPER_HXX_
#define _OSL_FILE_PATH_HELPER_HXX_

#ifndef _OSL_FILE_PATH_HELPER_H_
#include "file_path_helper.h"
#endif

#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

namespace osl
{

 /*******************************************
    systemPathRemoveSeparator
    Removes the last separator from the
    given system path if any and if the path
    is not the root path '/'

    @param  ppustrPath [inout] a system path
            if the path is not the root path
            and the last character is a
            path separator it will be cut off
               ppustrPath must not be NULL and
            must point to a valid rtl_uString

    @returns nothing

  ******************************************/

 inline void systemPathRemoveSeparator(/*inout*/ rtl::OUString& Path)
 {
     osl_systemPathRemoveSeparator(Path.pData);
 }

 /*******************************************
    systemPathEnsureSeparator
    Adds a trailing path separator to the
    given system path if not already there
    and if the path is not the root path '/'

      @param    pustrPath [inout] a system path
            if the path is not the root path
            '/' and has no trailing separator
            a separator will be added
            ppustrPath must not be NULL and
            must point to a valid rtl_uString

    @returns nothing

  ******************************************/

 inline void systemPathEnsureSeparator(/*inout*/ rtl::OUString& Path)
 {
     osl_systemPathEnsureSeparator(&Path.pData);
 }

 /*******************************************
    systemPathIsRelativePath
    Returns true if the given path is a
    relative path and so starts not with '/'

    @param  pustrPath [in] a system path
            pustrPath must not be NULL

    @returns sal_True if the given path
             doesn't start with a separator
             else sal_False will be returned

  ******************************************/

 inline bool systemPathIsRelativePath(const rtl::OUString& Path)
 {
    return osl_systemPathIsRelativePath(Path.pData);
 }

 /******************************************
    systemPathIsAbsolutePath
    Returns true if the given path is an
    absolute path and so starts with a '/'

    @param pustrPath [in] a system path
           pustrPath must not be NULL

    @returns sal_True if the given path
             start's with a separator else
             sal_False will be returned

  *****************************************/

 inline bool systemPathIsAbsolutePath(const rtl::OUString& Path)
 {
     return osl_systemPathIsAbsolutePath(Path.pData);
 }

 /******************************************
    systemPathMakeAbsolutePath
    Append a relative path to a base path

    @param  pustrBasePath [in] a system
            path that will be considered as
            base path
            pustrBasePath must not be NULL

    @param  pustrRelPath [in] a system path
            that will be considered as
            relative path
            pustrBasePath must not be NULL

    @param  ppustrAbsolutePath [out] the
            resulting path which is a
            concatination of the base and
            the relative path
            if base path is empty the
            resulting absolute path is the
            relative path
            if relative path is empty the
            resulting absolute path is the
            base path
            if base and relative path are
            empty the resulting absolute
            path is also empty
            ppustrAbsolutePath must not be
            NULL and *ppustrAbsolutePath
            must be 0 or point to a valid
            rtl_uString

  *****************************************/

 inline void systemPathMakeAbsolutePath(
     const rtl::OUString& BasePath,
    const rtl::OUString& RelPath,
    rtl::OUString&       AbsolutePath)
 {
    osl_systemPathMakeAbsolutePath(
        BasePath.pData, RelPath.pData, &AbsolutePath.pData);
 }

 /*****************************************
    systemPathGetParent
    Replaces the last occurrance of a path
    separator with '\0' and returns the
    position where the '/' was replaced

    @param  pustrPath [inout] a system
            path, the last separator of
            this path will be replaced by
            a '\0'
            if the path is the root path
            '/' or the path is considered
            as to have no parent, e.g.
            '/NoParent' or 'NoParent' or
            the path is empty no
            replacement will be made
            pustrPath must not be NULL

    @returns the position of the last path
             separator that was replaced
             or 0 if no replacement took
             place

  ****************************************/

 inline sal_Int32 systemPathGetParent(/*inout*/ rtl::OUString& Path)
 {
    return osl_systemPathGetParent(Path.pData);
 }

 /*****************************************
     systemPathGetFileOrLastDirectoryPart
    Returns the file or the directory part
    of the given path

    @param pustrPath [in] a system path,
           must not be NULL

    @param ppustrFileOrDirPart [out] on
           return receives the last part
           of the given directory or the
           file name
           if pustrPath is the root path
           '/' an empty string will be
           returned
           if pustrPath has a trailing
           '/' the last part before the
           '/' will be returned else
           the part after the last '/'
           will be returned

    @returns nothing

  ****************************************/

 inline void systemPathGetFileNameOrLastDirectoryPart(
     const rtl::OUString& Path,
    rtl::OUString&       FileNameOrLastDirPart)
 {
    osl_systemPathGetFileNameOrLastDirectoryPart(
        Path.pData, &FileNameOrLastDirPart.pData);
 }

 /********************************************
     systemPathIsHiddenFileOrDirectoryEntry
    Returns sal_True if the last part of
    given system path is not '.' or '..'
    alone and starts with a '.'

    @param pustrPath [in] a system path,
           must not be NULL

    @returns sal_True if the last part of
             the given system path starts
             with '.' or sal_False the last
             part is '.' or '..' alone or
             doesn't start with a dot

 *********************************************/

 inline bool systemPathIsHiddenFileOrDirectoryEntry(
     const rtl::OUString& Path)
 {
    return osl_systemPathIsHiddenFileOrDirectoryEntry(Path.pData);
 }

 /************************************************
     systemPathIsLocalOrParentDirectoryEntry
    Returns sal_True if the last part of the given
    system path is the local directory entry '.'
    or the parent directory entry '..'

    @param pustrPath [in] a system path,
           must not be NULL

    @returns sal_True if the last part of the
             given system path is '.' or '..'
             else sal_False

 ************************************************/

 inline bool systemPathIsLocalOrParentDirectoryEntry(
     const rtl::OUString& Path)
 {
    return osl_systemPathIsLocalOrParentDirectoryEntry(Path.pData);
 }

 /************************************************
  searchPath
  ***********************************************/

 inline bool searchPath(
     const rtl::OUString& ustrFilePath,
    const rtl::OUString& ustrSearchPathList,
    rtl::OUString& ustrPathFound)
 {
     return osl_searchPath(
        ustrFilePath.pData,
        ustrSearchPathList.pData,
        &ustrPathFound.pData);
 }

 } // namespace osl

 #endif /* #ifndef _OSL_PATH_HELPER_HXX_ */

<|endoftext|>