1. How to build the boost library
2. How to install the boost library (without building)
2.2. MacOS X
brew install boost
The library will be installed to a versioned subfolder of /usr/local/Cellar/boost, e. g. /usr/local/Cellar/boost/1.70.0
2.3. Windows
Install the version matching your compiler from https://sourceforge.net/projects/boost/files/boost-binaries. The default location is a versioned subfolder at C:\local, e. g. C:\local\boost_1_70_0
3. Complex numbers
math_samples.hpp
#pragma once
void math_samples();
math_samples.cpp
#include "math_samples.hpp"
#include <iostream>
#include <complex>
#include <boost/rational.hpp>
void math_samples()
{
std::complex<boost::rational<int>> a,b;
boost::rational<int> pi(355, 113);
std::cout << "Pi is approximately " << boost::rational_cast<double>(pi) << std::endl;
using namespace std::complex_literals;
std::cout << std::fixed << std::setprecision(1);
std::complex<double> z1 = 1i * 1i; // imaginary unit squared
std::cout << "i * i = " << z1 << " = " << z1.real() << std::endl;
std::complex<double> z2 = std::pow(1i, 2); // imaginary unit squared
std::cout << "pow(i, 2) = " << z2 << " = " << z2.real() << std::endl;
double PI = std::acos(-1);
std::complex<double> z3 = std::exp(1i * PI); // Euler's formula
std::cout << "e^(i * pi) = " << z3 << " = " << z3.real() << std::endl;
std::complex<double> z4 = 1. + 2i, z5 = 1. - 2i; // conjugates
std::cout << "(1+2i)*(1-2i) = " << z4*z5 << " = " << (z4*z5).real() << std::endl;
}
4. Parser
parser.hpp
#pragma once
#include <string>
// several ways how to use boost::spirit to parse a list of numbers like "3, 3.14, -2.5, 790" and a complex number like "(1.0, -4.0)"
void parser_sample(std::string numberList, std::string complexNumber);
parser.cpp
#include "parser.hpp"
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
void print(double const& val)
{
std::cout << "Parsed number = " << val << std::endl;
}
template <typename Iterator>
bool parse_number_list(Iterator first, Iterator last)
{
using boost::spirit::qi::double_;
using boost::spirit::qi::rule;
using boost::spirit::qi::phrase_parse;
using boost::spirit::ascii::space;
bool r = phrase_parse(
first, /*< start iterator >*/
last, /*< end iterator >*/
double_[&print] >> *(',' >> double_[&print]), /*< the parser >*/
space /*< the skip-parser >*/
);
if (first != last) // fail if we did not get a full match
return false;
return r;
}
template <typename Iterator>
bool parse_four_numbers(Iterator first, Iterator last, double& a, double& b, double& c, double& d)
{
using boost::spirit::qi::double_;
using boost::spirit::qi::_1;
using boost::spirit::qi::phrase_parse;
using boost::spirit::ascii::space;
using boost::phoenix::ref;
bool r = phrase_parse(
first,
last,
double_[ref(a) = _1] >> ',' >>
double_[ref(b) = _1] >> ',' >>
double_[ref(c) = _1] >> ',' >>
double_[ref(d) = _1],
space);
if (!r || first != last) // fail if we did not get a full match
return false;
return r;
}
template <typename Iterator>
bool parse_numbers_into_vector(Iterator first, Iterator last, std::vector<double>& v)
{
using boost::spirit::qi::double_;
using boost::spirit::qi::phrase_parse;
using boost::spirit::qi::_1;
using boost::spirit::ascii::space;
bool r = phrase_parse(
first,
last,
double_ % ',',
space,
v);
if (first != last) // fail if we did not get a full match
return false;
return r;
}
template <typename Iterator>
bool parse_complex(Iterator first, Iterator last, std::complex<double>& c)
{
using boost::spirit::qi::double_;
using boost::spirit::qi::_1;
using boost::spirit::qi::phrase_parse;
using boost::spirit::ascii::space;
using boost::phoenix::ref;
double rN = 0.0;
double iN = 0.0;
bool r = phrase_parse(first, last,
// Begin grammar
(
'(' >> double_[ref(rN) = _1]
>> -(',' >> double_[ref(iN) = _1]) >> ')'
| double_[ref(rN) = _1]
),
// End grammar
space);
if (!r || first != last) // fail if we did not get a full match
return false;
c = std::complex<double>(rN, iN);
return r;
}
void parser_sample(std::string numberList, std::string complexNumber)
{
if (parse_number_list(numberList.begin(), numberList.end()))
{
std::cout << "Parsing number list succeeded" << std::endl;
}
else
{
std::cout << "Parsing number list failed" << std::endl;
}
double a, b, c, d;
if (parse_four_numbers(numberList.begin(), numberList.end(), a, b, c, d))
{
std::cout << "Parsing 4 numbers succeeded: " << a << " " << b << " " << c << " " << d << std::endl;
}
else
{
std::cout << "Parsing 4 numbers failed" << std::endl;
}
std::vector<double> result;
if (parse_numbers_into_vector(numberList.begin(), numberList.end(), result))
{
std::cout << "Parsing numbers into std::vector succeeded: ";
for (double& val : result) std::cout << val << " ";
std::cout << std::endl;
}
else
{
std::cout << "Parsing numbers into std::vector failed" << std::endl;
}
std::complex<double> cpl;
if (parse_complex(complexNumber.begin(), complexNumber.end(), cpl))
{
std::cout << "Parsed complex number " << cpl << std::endl;
}
else
{
std::cout << "Parsing complex number failed." << std::endl;
}
}
5. Sockets
socket.hpp
#pragma once
#include<string>
bool send_to_socket(std::string address, int port, std::string content);
socket.cpp
#include "socket.hpp"
#ifdef _WIN32
#define _WIN32_WINNT 0x0601 //_WIN32_WINNT_WIN7
#endif
#include <boost/asio.hpp>
bool send_to_socket(std::string address, int port, std::string content)
{
boost::asio::io_service io_service;
boost::asio::ip::tcp::socket socket(io_service);
connect(socket, boost::asio::ip::tcp::resolver(io_service).resolve({address, std::to_string(port)}));
return write(socket, boost::asio::buffer(content)) == content.length();
}
6. Read and write XML
demo.xml
<?xml version="1.0" encoding="UTF-8"?>
<SZSamples>
<title>sample xml file</title>
<version>1</version>
<point>
<x>10.38</x>
<y>1.81</y>
</point>
<point>
<x>5.45</x>
<y>-3.68</y>
</point>
<point>
<x>5.89</x>
<y>5.49</y>
</point>
</SZSamples>
xml.hpp
#pragma once
#include <string>
#include <vector>
// read and write an xml file containing a title, a version and a list of x/y coordinates
void read_xml(std::string filename, std::string& title, int& version, std::vector<std::pair<double, double>>& coordList);
void write_properties(std::string filename, std::string title, int version, std::vector<std::pair<double, double>> coordList);
xml.cpp
#include "xml.hpp"
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
// includes to write additional formats info and json
#include <boost/property_tree/info_parser.hpp>
#include <boost/property_tree/json_parser.hpp>
void read_xml(std::string filename, std::string& title, int& version, std::vector<std::pair<double, double>>& coordList)
{
boost::property_tree::ptree tree;
boost::property_tree::xml_parser::read_xml(filename, tree);
title = tree.get<std::string>("SZSamples.title");
version = tree.get<int>("SZSamples.version");
for (boost::property_tree::ptree::value_type& v : tree.get_child("SZSamples"))
{
if (v.first == "point")
{
double x = v.second.get<double>("x");
double y = v.second.get<double>("y");
coordList.emplace_back(std::make_pair(x, y));
}
}
}
void write_properties(std::string filename, std::string title, int version, std::vector<std::pair<double, double>> coordList)
{
boost::property_tree::ptree tree;
tree.put("SZSamples.title", title);
tree.put("SZSamples.version", version);
for (auto coord : coordList)
{
boost::property_tree::ptree point;
point.add("x", coord.first);
point.add("y", coord.second);
tree.add_child("SZSamples.point", point);
}
boost::property_tree::write_xml(filename+".xml", tree);
boost::property_tree::write_info(filename+".ini", tree);
boost::property_tree::write_json(filename+".json", tree);
}