Geeks With Blogs
Josh Reuben

Beyond C++ and the standard library, and before you dive into the massive Qt ecosystem, you can expand your C++ repertoire by familiarizing yourself with the Boost libraries. Now a fair chunk of this has been absorbed into C++11 standard library, so I've taken the time to identify the remaining Boost components that will provide added value to modern C++ dev, and will most likely osmosize their functionality into C++17 !

The Redundant Parts

If you are not using GCC or LLVM as your compiler, then you will most likely need to leverage these APIs to get modern C++ functionality:
  • Boost.Any (replaced by std::auto)

  • Boost.Array (replaced by std::array)

  • Boost.Atomic (replaced by std::atomic)

  • Boost.Chrono (replaced by std::chrono)

  • Boost.Concept_Check (Replace by C++vnext Concepts)

  • Boost.Date_Time (Replaced by C++11 std::chrono::)

  • Boost.Foreach (Replaced by C++11 ranged for)

  • Boost.Function (replaced by std::function)

  • Boost.Functional/Hash (Replaced by std::hash<T>)

  • Boost.Heap (Replaced by std::priority_queue)

  • Boost.Intrusive (Replaced by STL Container move constructor / assignment)

  • Boost.Lambda (Replaced by C++11 Lambdas)

  • Boost.Random (Replaced by std::default_random_engine)

  • Boost.Ratio 2.0.0 (Replace with std::ratio)

  • Boost.Ref (Replaced by std::ref)

  • Boost.Move (Replaced with std::move)

  • Boost.StaticAssert (Replaced by std::static_assert)

  • Boost String Algorithms Library

  • Boost.Typeof (Replaced by decltype)

  • Boost.Units (Replaced by std::ratio constexpr)

  • Boost.Unordered (Replaced by std::unordered_set / std::unordered_multiset)

  • Boost.Xpressive (Replaced by std::regex_match)

  • Boost.TypeErasure (Replaced by C++14 auto lambdas)


Boost.Interprocess

using namespace boost::interprocess;

Features:

  • mapped memory regions - fixed-length memory buffers mapped as shared memory or memory-mapped files

  • Semaphores, mutexes, condition variables and upgradable mutexes – replaced by std::memory

  • Message queues.

Sharing memory between processes – 3 mechanisms:

  • via read/write file. Requires manual synchronization.

  • via OS kernel - eg message queues. synchronization is guaranteed by the kernel.

  • via a shared memory region - classical shared memory or memory mapped files. Requires manual synchronization. FASTEST!

leverages Linux: POSIX for native IPC , file permissions for synchronization / shared memory mode. OS maps a memory segment in the address space of several processes – they can read / write in that memory segment without calling OS functions.

both shared_memory_object and file_mapping objects can be used to create mapped_region objects.

Limitations When Constructing Objects In Mapped Regions - References and Virtuality are forbidden

Synchronization mechanisms:

  • Boost.Threads implements these synchronization utilities between threads inside the same process.

  • Boost.Interprocess implements similar mechanisms to synchronize threads from different processes.


managed_shared_memory

Mechanism: allocate a portion of a shared memory segment. Create named objects in it - provide a string key so that other process can find, use and delete them from the segment:

managed_shared_memory segment(open_or_create, "MySharedMemory", intSize);

// other options: create_only, open_only

void * shptr = segment.allocate(2048); //alloc 2048 bytes of raw memory

managed_shared_memory::handle_t handle = segment.get_handle_from_address(shptr);

// find / construct / find_or_construct

MyType *p_o = segment.find_or_construct <MyType>("MyInstance") (/* ctor params);

...

p_o = segment.find<MyType>("MyInstance");

segment.destroy<MyType>("MyInstance");

//Get buffer local address from handle

void *msg = segment.get_address_from_handle(handle);

segment.deallocate(msg);

...

// validate free memory size as needed:

managed_shared_memory::size_type free_memory_size = segment.get_free_memory();


Shared_memory_object

shared_memory_object smo

(open_or_create //other options: open_only / create_only

,sName

,read_write //other options: read_only / write_only

);

smo.truncate(10000); // an smo is created with size 0 – use truncate to set size

As shared memory has kernel or filesystem persistence, the user must explicitly destroy it via remove:

// map all / part of shared memory object (eg obj) into the process' address space using the mapped_region class.

mapped_region region(smo, read_write /*mode*/, smoSize, regionSize /*size_t*/);

region.get_address();

region.get_size();

shared_memory_object::remove(smo);

Anonymous shared memory - When processes are related via fork(), a simpler method is available using anonymous shared memory, mapping the device /dev/zero.

//Create an anonymous shared memory segment with size 1000

mapped_region region(anonymous_shared_memory(1000));

//Write all the memory to 1

memset(region.get_address(), 1, region.get_size());



file_mapping

memory mapped files - associate a file's contents with a one or more mapped regions of a process address space . Processes read / write to the file using pointers, just like with dynamic memory. advantages:

  • Uniform resource use.

  • Automatic file data synchronization and cache from the OS.

  • Reuse of C++ utilities (STL containers, algorithms) in files.

  • Shared memory between two or more applications.

  • efficient for large files – dont have to mapp whole file into memory

  • multiple process' views point to identical copies of the file on disk.

OS must synchronize file contents with memory --> not as fast an IPC as shared memory.

file_mapping m_file("/usr/home/file" /*filename*/,read_write /*mode*/);

Mapping File's Contents to all / part of Memory of process' address space:

mapped_region region(file, read_write /*mode*/, fileSize, regionSize);

changes are imediatelly visible to other processes. However, the file contents on disk are not updated immediately, since that would hurt performance - can manually flush a range from the view to disk:

region.flush(offset, size);



offset_ptr<T>

a smart pointer that can point safely to objects stored in the same shared memory segmenteg use to create a linked list in shared memory mapped at different base addresses in different processes.

Mapping Address In Several Processes - avoid using raw pointers, use offset_ptr which can be safely placed in shared memory / memory mapped file.

mapped_region region ( shm, read_write

, 0 , 0 //Map from offset 0 until the end

, (void*)0x2D000000); //Map it exactly there

the mapping address and the offset of the mappable object must be a multiple of the page size.

size_t page_size = mapped_region::get_page_size();



Message Queue

Threads can enqueue / dequeue messages in the priority queue using 3 methods:

  • Blocking: If Q is full when sending or is empty when receiving, the thread is blocked until there is room for a new message or there is a new message.

  • Try: If Q is full when sending or is empty when receiving, the thread returns immediately with an error.

  • Timed: If Q is full when sending or is empty when receiving, the thread retries the operation until succeeds (returning successful state) or a timeout is reached (returning a failure).

A message queue just copies raw bytes between processes and does not send objects. The object must be binary serializable. The message queue is created with a name , a maximum message size and a maximum message number.

message_queue mq(open_or_create ,sQueueName ,nMaxMessages, nMaxMessageSize);

for(int i = 0; i < 100; ++i){

mq.send(&i, sizeof(i), 0);

...

// in 2nd process:

for(int i = 0; i < 100; ++i){

int number;

mq.receive(&number, sizeof(number), recvd_size, priority);

...

message_queue::remove(sQueueName); // explicit removal



Boost.Lockfree

using namespace boost::atomic;

using namespace boost::lockfree;

Data structure terminology

  • non-blockingimplicitly concurrent user-space sync via atomic ops for optimal latency.do not rely on kernel locks and mutexes. Hardware dependent

  • Wait-free - every concurrent op is guaranteed to finish in a finite number of steps.

  • Lock-free - some concurrent ops are guaranteed to finish in a finite number of steps.

  • Obstruction-free - a concurrent op is guaranteed to finish in a finite number of steps, unless another concurrent op interferes.

3 lock-free data structures that intermediate between producer & consumer threads.

  • queue - lock-free multi-producer/multi-consumer

  • stack - lock-free multi-producer/multi-consumer

  • spsc_queue - wait-free single-producer/single-consumer (ringbuffer)

Data Structures are configured with Boost.Parameter-style templates: fixed_sized<int> , capacity<int>, allocator<int>

queue<int> queue(128);

queue.push(value);

...

queue.pop(value);

thread_group::create_thread(myMethod);

thread_group::join_all();

spsc_queue<int, capacity<1024> > spsc_queue;


Boost.MPI

using namespace boost::mpi;

using namespace boost::mpi::threading;

HPC inter-process communication via ptp or collective message passing .

Boost provides a Python (boost_mpi_python) and C++ abstraction to the C MPI standard that supports the creation, destruction, cloning, and splitting of MPI communicators & process groups. Need to leverage an underlying MPI implementation eg Open MPI, LAM/MPI, MPICH2. Note: Allot of standard C MPI has no Boost.MPI equivalents.

An MPI program consists of many cooperating processes (possibly running on different computers) that communicate among themselves by passing messages over a communicator. Each message has a source process, a target process (ranks of the sender and receiver), a tag, and a payload containing primitive or user-defined data types & functors.

#include <boost/mpi/environment.hpp>

#include <boost/mpi/communicator.hpp>


mpi::environment env; // initializes the MPI environment and enables communication

mpi::communicator comm; // assigns a unique rank id to each process

// & supports querying total number

cout << "id" << comm.rank() << " out of " << comm.size() << endl;

Point-to-point ops

send and receive blocking / non-blocking ops

// sync blocking

string msg;

if (comm.rank() == 0) {

comm.send(1, 0, string("Hello"));

comm.recv(1, 1, msg);

cout << msg << "!" << endl;

} else {

comm.recv(0, 0, msg);

cout << msg << ", ";

cout.flush();

comm.send(0, 1, string("comm"));

}

// assync – prefix i

request reqs[2];

if (comm.rank() == 0) {

reqs[0] = comm.isend(1, 0, msg);

reqs[1] = comm.irecv(1, 1, msg);

wait_all(reqs, reqs + 2);

} else {

reqs[0] = comm.isend(0, 1, out_msg);

reqs[1] = comm.irecv(0, 0, msg);

wait_all(reqs, reqs + 2);

}

user defined datatypes must be serializable - see type trait is_mpi_datatype<T>

friend class boost::serialization::access;

template<class Archive>

void serialize(Archive & ar, const unsigned int version){

ar & xxx;

...

}

Collective ops

Broadcast

if (comm.rank() == 0) {

broadcast(comm, msg, 0); // send to all


Gather - collect values produced by every process in a communicator into a vector of values on the master process.

reduce – use a functor to aggregate values from each process into a single value on the master process – like STL accumulate.

if (comm.rank() == 0) {

vector<int> all_numbers;

int average;

gather(comm, rand(), all_numbers, 0); // gather random numbers from each

reduce(comm, rand(), average, mpi::average<int>(), 0);

} else {

gather(comm, rand(), 0);

reduce(comm, rand(), mpi::average<int>(), 0);

}

ops have "all" variant all_reduce / all_gather - performs the operation and broadcasts the result to all processes.

Managing communicators

Other communicator “subnets” can be constructed by splitting.

bool is_generator = comm.rank() < 2 * comm.size() / 3;

communicator local = comm.split(is_generator? 0 : 1);

if (is_generator) generate_data(local, comm);

else collect_data(local, comm);

probe a message's rank as input into control flow decisions messaging:

status msg = comm.probe();

if (msg.tag() == msg_data_packet) {

comm.recv(msg.source(), msg.tag(), data);

group provides facilities to compute the union (|), intersection (&), and difference (-) of two groups, generate arbitrary subgroups, etc.

Boost.PropertyTree

provides an arbitrary tree data structure of indexed KVP nodes, with easy concatenated path access (eg level1.level2.level3) and various data format representations (XML, INI, JSON). suited for holding configuration data:

using namespace boost::property_tree;

vector<string> grandchildren = { "aaa", "bbb", "ccc" };

ptree pt1, pt2;

stringstream ss;


pt1.put("parent.child1", "xxx");

pt1.put("parent.child2", 5.0);

for ( const auto &v : grandchildren) {

ptree pt3;

pt3.put("e1", v);

pt1.add_child("parent.grandchildren.grandchild", pt3);

}

write_xml(ss, pt1);


read_xml(ss, pt2);

cout << pt2.get<string>("parent.child1") << endl;

cout << pt2.get("parent.child2", 0) << endl;

for (const auto &v : pt2.get_child("parent.grandchildren")) {

cout << v.second.data() << endl;

}

Boost.Proto

An API for constructing expression trees for embedding DSLs in C++.

namespaces: boost::mpl; boost::fusion;boost::proto;

Entity

Example

Free Function

boost::proto::value()

Metafunction

boost::proto::result_of::value<>

Function Object

boost::proto::functional::value

Transform

boost::proto::_value


I found this to be too esetoric to dive into.

Boost.Signals2

using namespace boost::signals2;

A pubsub system of signals and slots . Signals are publishers - callbacks with multiple targets, connected to slots ( subscribers ie callback receivers), which are called when the event is published.

Managed - track signal/slot connections, manage their lifetimes and automatically disconnect connections when either is destroyed.

Signals2 - thread-safe , automatic connection management.

Calling slots

struct MyFunctor{

void operator()() const {

cout << "blah" << endl;

}

};

signal<void ()> sig; // Signal with no args or retval


MyFunctor f;

sig.connect(f()); // Connect a functor slot to the signal

sig(); // Call all of the slots



Calling multiple slots - Can connect multiple slots and order slot call groups in the slot list

sig.connect(1, f()); // connect with group 1

sig.connect(0, g()); // connect with group 0

unnamed slots (i.e., those connected without specifying a group name) can be placed at the front or back of the slot list (by passing at_front or at_back as the last parameter to connect), and default to the end of the list.

slots are invoked in order:1) ungrouped slots connected with at_front; 2) grouped slots according to ordering of their groups;3) ungrouped slots connected with at_back

Passing Values to and from Slots

Eg a Slot with 2 Args and a retval

float product(float x, float y) { return x * y; }

signal<float (float, float)> sig;

sig.connect(&product);

float result = *sig(5., 10.);

Signal Return Values - values can be returned back to the caller of the signal through an optional combiner: The default combiner returns a boost::optional containing the return value of the last slot in the slot list.Can create a custom combiner functor and pass it to the signal constructor template – can return a scalar, a vector, apply filtering etc.

signal<float (float x, float y), maximum<float> > sig;

Slot functors can be passed via slot_type (IMHO: use decltype)

typedef signal<void (int x, int y)> OnClick;

typedef OnClick::slot_type OnClickSlotType;

// forward slots through Button interface to its private signal

connection doOnClick(const OnClickSlotType & slot);

Connection Lifetime Management

connection class represents the connection between a particular signal and a particular slot. The connected() method checks if the signal and slot are still connected, and the disconnect() method disconnects the signal and slot if they are connected before it is called.

connection c = sig.connect(f());

sig();

c.disconnect();

sig(); // Does nothing: there are no connected slots

Blocking Slots - shared_connection_block object will temporarily block a slot ignored when the signal is invoked (egused to prevent infinite recursion) . The connection is unblocked by either destroying or calling unblock:

connection c = sig.connect(f());

{

boost::signals2::shared_connection_block block(c); // block the slot

} // block going out of scope unblocks the slot

scoped_connection object - a signal/slot connection that will be disconnected when the scoped_connection class goes out of scope. For temporary connections:

{

scoped_connection c(sig.connect(ShortLived()));

sig(); // will call ShortLived functor

} goes out of scope and disconnects

use disconnect method to disconnect specific slots by functor instance:

sig.connect(&f);

sig.connect(&g);

sig();

sig.disconnect(&foo); // disconnects f but not g

Automatic Connection Management - automatic disconnection of slots occurs when objects involved in the slot call are destroyed - track any object which is managed by a shared_ptr, by using slot::track_foreign. no explicit call to bind() needed for object paramsits implicit.

shared_ptr<MyFunctor> pf(new MyFunctor());

sig

.connect(signal_type::slot_type(&pf,pf.get(),_1)

.track_foreign(newsMessageArea));

Signal/slot disconnections occur when:

  • explicit disconnection via signal::disconnect / connection::disconnect

  • scoped_connection's destructor.

  • An object tracked by the slot is destroyed.

  • The signal is destroyed.

to disconnect or block a slot's connection from within the slot itself, signal::connect_extended methods allow slots which take an extra connection argument to be connected to a signal.

Changing the Mutex Type of a Signal - to use an alternate mutex type to the default boost::signals2::mutex, it must be default-constructible and fulfill the Lockable concept defined by the Boost.Thread library (it must have lock() and unlock() methods). Boost provides an alternate mutex class dummy_mutex - a fake for use in single-threaded programs, where locking a real mutex would be useless overhead.



Boost.Asio

using namespace boost::asio;

using namespace boost::asio::ip;

perform synchronous / asynchronous operations on I/O objects such as sockets.

io_service object – socket uses this as an interface to the underlying OS I/O services.

io_service io_service;

error_code ec;

socket.connect(server_endpoint, ec);

or

socket.async_connect(server_endpoint, my_completion_handler);

..

void my_completion_handler(const error_code& ec);

call io_service::run() for result to be retrieved- blocks while there are unfinished asynchronous operations. This is thread-safe.io_service::post() supports threadpools.

Boost.Asio implements the Proactor Design Pattern (concurrency without threads http://en.wikipedia.org/wiki/Proactor_pattern )

Strands: Use Threads Without Explicit Locking - io_service::strand::wrap() - for sequential invocation of event handler functors --> avoid explicit mutex locking.

Buffers


mutable_buffer and const_buffer provide protection against buffer overruns and type safety via buffer_cast

support for scatter-gather operations:A scatter-read receives data into multiple buffers, and a gather-write transmits multiple buffers via buffer containers MutableBufferSequence and ConstBufferSequence.

basic_streambuf provides iostream integration - data() exposes input sequence and prepare() exposes output sequence. commit() publishes data and consume() subscribes it.


Streams, Short Reads and Short Writes

sync / async stream support:: read_some(), async_read_some(), write_some().

stream-oriented I/O objects include ip::tcp::socket, ssl::stream<>, posix::stream_descriptor.

See: async_read(), async_write(), read(), write(), AsyncReadStream, AsyncWriteStream, SyncReadStream, SyncWriteStream.


Operations

Reactor-Style Ops - 3rd party integration - See null_buffers, basic_socket::non_blocking(), basic_socket::native_non_blocking()

Line-Based Ops - Many internet application protocols (eg HTTP, FTP) are line-based - char delimited by "\r\n". For this, use read_until() / async_read_until().

using namespace boost;

using namespace boost::system;

tcp::socket socket_;

streambuf data_; //store data read from socket


async_read_until(socket_, data_, "\r\n",

boost::bind(&http_connection::handle_request_line, this, _1));


void handle_request_line(error_code ec){

if (!ec) istream is(&data_);

The delimiters may be specified as a single char, a string or a boost::regex. The functions also include overloads that accept a functor that matches via the is_match_condition<> type trait

streambuf b;

read_until(s, b, match_char('a'));

Custom Memory Allocation - If a protocol handler requires allocating temp memory , use:

void* asio_handler_allocate(size_t, ...);

void asio_handler_deallocate(void*, size_t, ...);

Handler Tracking - for debugging asynchronous programs, define BOOST_ASIO_ENABLE_HANDLER_TRACKING symbol for stderr dumping.


Coroutines

coroutine class - implement asynchronous logic in a synchronous manner, with minimal overhead (ie stackless):

struct session : coroutine {

shared_ptr<tcp::socket> socket_;

shared_ptr<vector<char> > buffer_;


session(shared_ptr<socket> socket)

: socket_(socket), buffer_(new vector<char>(1024))

{}


void operator()(error_code ec = error_code(), size_t n = 0){

if (!ec) reenter (this){

for (;;){

yield socket_->async_read_some(buffer(*buffer_), *this);

yield async_write(*socket_, buffer(*buffer_, n), *this);


used in conjunction with the pseudo-keywords reenter, yield and fork, which are preprocessor macros.

The spawn() function is a high-level wrapper for running stackful coroutines:

spawn(my_strand, do_echo);

void do_echo(yield_context yield){

char data[128];

for (;;){

size_t length = my_socket.async_read_some(buffer(data), yield);

async_write(my_socket, buffer(data, length), yield);

TCP, UDP && ICMP

Boost.Asio provides off-the-shelf support for the internet protocols TCP, UDP and ICMP.

TCP Clients - Hostname resolution is performed using a resolver:

resolver resolver(my_io_service);

resolver::query query("www.boost.org", "http");

resolver::iterator iter = resolver.resolve(query);

resolver::iterator end; // End marker.

while (iter != end){

endpoint endpoint = *iter++;

TCP clients establish connections using connect() and async_connect():

socket socket(my_io_service);

connect(socket, resolver.resolve(query));

// or asynchronous connect:

async_connect(socket_,iter, bind(&client::handle_connect, this, placeholders::error));

...

void handle_connect(const error_code& error){

When a specific endpoint is available, a socket can be created and connected:

socket.connect(endpoint);

Data may be read from or written to a connected TCP socket using: read(), async_read(), write() and async_write().


TCP Servers - use an acceptor

acceptor acceptor(my_io_service, my_endpoint);

socket socket(my_io_service);

acceptor.accept(socket);


UDP - hostname resolution is also performed using a resolver, typically bound to a local endpoint. The following code will create an IP version 4 UDP socket and bind it to the "any" address on port 12345:

ip::udp::endpoint endpoint(ip::udp::v4(), 12345);

ip::icmp::endpoint endpoint(ip::icmp::v6(), 0);

The port number is not used for ICMP.

For a connected UDP socket, use the receive(), async_receive(), send() or async_send() m; for unconnected ICMP socket use receive_from(), async_receive_from(), send_to() or async_send_to()


Support for other socket protocols - (such as Bluetooth or IRCOMM sockets) can be added by deriving from one of these classes:

generic::datagram_protocol

generic::raw_protocol

generic::seq_packet_protocol

generic::stream_protocol



Socket Iostreams

iostreams are abstracted on top of sockets - protocol independence, etc.:

ip::tcp::iostream stream("www.boost.org", "http");

can be used with an acceptor to create simple servers:

io_service ios;


tcp::endpoint endpoint(tcp::v4(), 80);

tcp::acceptor acceptor(ios, endpoint);


for (;;){

ip::tcp::iostream stream;

acceptor.accept(*stream.rdbuf());

Timeouts may be set by calling expires_at() or expires_from_now():

ip::tcp::iostream stream;

stream.expires_from_now(boost::posix_time::seconds(60));

stream.connect("www.boost.org", "http");

stream << "blah\r\n";

stream.flush();

cout << stream.rdbuf();

will fail if all the socket operations combined take longer than 60 seconds.

If an error does occur, the iostream's error() member function may be used to retrieve the error code from the most recent system call:

if (!stream){

cout << "Error: " << stream.error().message() << "\n";

See ip::tcp::iostream, basic_socket_iostream, iostreams examples.


BSD Sockets

The Boost.Asio library includes a low-level socket interface based on the BSD socket API:

Timers

eg perform a synchronous wait operation on a timer using a relative time:

io_service i;

...

deadline_timer t(i);

t.expires_from_now(seconds(5));

t.wait();

eg perform an asynchronous wait operation on a timer:

void handler(error_code ec) { ... }

...

io_service i;

...

deadline_timer t(i);

t.expires_from_now(milliseconds(400));

t.async_wait(handler);

...

i.run();

The deadline associated with a timer may also be obtained as a relative time:

time_duration time_until_expiry = t.expires_from_now();

or as an absolute time to allow composition of timers:

t2.expires_at(t.expires_at() + seconds(30));

Serial Ports

a serial port may be opened using:

serial_port port(my_io_service, "/dev/ttyS0");

Once opened, the serial port may be used as a stream.

Signal Handling

Add signals to one or more signal_set objects, then perform an async_wait() operation.

// Construct a signal set registered for process termination.

signal_set signals(io_service, SIGINT, SIGTERM);


// Start an asynchronous wait for one of the signals to occur.

signals.async_wait(handler);


UNIX Domain Sockets - Boost.Asio provides basic support UNIX domain sockets

See: local::connect_pair, local::datagram_protocol, local::datagram_protocol::endpoint, local::datagram_protocol::socket, local::stream_protocol, local::stream_protocol::acceptor, local::stream_protocol::endpoint, local::stream_protocol::iostream, local::stream_protocol::socket, UNIX domain sockets examples.

Stream-Oriented File Descriptors

Boost.Asio includes classes added to permit synchronous and asynchronous read and write operations to be performed on POSIX file descriptors, such as pipes, standard IO, and various devices (but not regular files).

See posix::stream_descriptor, posix::basic_stream_descriptor, posix::stream_descriptor_service

Fork

Boost.Asio supports process forking and parent child notifications:

io_service_.notify_fork(fork_prepare);

if (fork() == 0){

io_service_.notify_fork(fork_child);

...

} else {

io_service_.notify_fork(fork_parent);

...

}

SSL

can layer encrypted comms over an existing stream, such as a TCP socket.

ssl::context ctx(ssl::context::sslv23);

ctx.set_verify_mode(ssl::verify_peer);

ctx.load_verify_file("ca.pem");

To use SSL with a TCP socket, one may write:

ssl::stream<tcp::socket> ssl_sock(my_io_service, ctx);

To perform socket-specific operations, such as establishing an outbound connection or accepting an incoming one, the underlying socket must first be obtained:

tcp::socket::lowest_layer_type& sock = ssl_sock.lowest_layer();

sock.connect(my_endpoint);

for configuring SSL certificate verifiication:

ssl::context::set_default_verify_paths()

ssl::context::set_verify_mode()

ssl::context::set_verify_callback()

ssl::context::load_verify_file()

ssl::stream::set_verify_mode()

ssl::stream::set_verify_callback()

Timers

Boost.Asio provides chrono timers via the basic_waitable_timer class template. The typedefs system_timer, steady_timer and high_resolution_timer utilise the standard clocks system_clock, steady_clock and high_resolution_clock respectively.


Boost.Accumulators

Framework for performing statistical computation and incremental calculations. An accumulator is a concrete primitive computational entity. Instantiate an accumulator_set<>, specifying built in / custom computations, push data in one sample at a time --> it will calculate the computations specified

accumulator_set<double, stats<tag::mean, tag::varience > > acc;

// push in some data ...

acc(1.1);

acc(2.2);

acc(3.3);

// Display the results ...

cout << "Varience: " << varience(acc) << endl;

API



accumulator_set<>

datum pushed in is forwarded to each accumulator in the set

depends_on<>

specify which other features a feature depends on.

feature_of<>

one feature should be treated the same as another.

as_feature<>

create an alias for a feature

features<>

An MPL sequence

external<>

store weight accumulators in a separate accumulator set

extractor<>

functor used to extract a result

template< typename Sample, typename Features, typename Weight = void >

struct accumulator_set;

template parameters:

  • Sample - type of the data that will be accumulated.

  • Features - An MPL sequence of features to be calculated. A feature is an abstract primitive computational entity.

  • Weight-The type of the (optional) weight scalar paramter.

Extracting Results - For each added feature from boost::accumulators , there is a corresponding extractor with same name for fetching its result in boost::accumulators::extract namespace.

Can also extract explicitly with extract_result()

can define custom extractors using the extractor<> class template.

Passing Optional Parameters - with named parameters from the Boost.Parameter library.

Weighted Samples - Each sample pushed into the accumulator has an associated weight, by which the sample is conceptually multiplied. specify the type of the weight parameter as the 3rd template parameter --> all the accumulators in the set are replaced with their weighted equivalents.

Defining a New Accumulator - inherit from accumulator_base and satisfy the Accumulator Concept.

Droppable Accumulators - an accumulator that can be removed from the accumulator_set<> using the droppable<> class template.

Defining a New Feature - inherit from depends_on<> to specify dependencies, satisfy the Feature Concept.Define a nested typedef called 'impl' that specifies which accumulator implements this feature.The nested impl type must be an MPL Lambda Expression. --> use of MPL placeholders like mpl::_1

Aliasing feature dependencies with feature_of<> - inform the Accumulators Framework that two features are the same from the point of view of dependency resolution

Register feature variants with as_feature<>

Miscalaneous Boost Features

Boost.Container

  • Replaced by move, emplace_back, multi-containers

  • Move semantics emulation for pre-C++11 compilers.

  • placement insertion, recursive containers

  • compatible with Boost.Interprocess ( can be safely placed in shared memory)

  • allocator_traits is the protocol between a container and an allocator – level of abstraction for stateful allocators

  • C++11 stateful allocators - scoped_allocator_adaptor class

Boost.Circular Buffer (Like Disruptor)

boost::circular_buffer is a STL compliant container (eg push_back)

There is also a circular_buffer_space_optimized version available.

circular_buffer<int> cb(10); // buffer has capacity for 10 integers.

like other STL implementations,the circular_buffer is not fully thread-safe.

The circular_buffer should not be used for storing pointers to dynamically allocated objects --> memory leaks.

Numeric Operators Sub-Library

boost::numeric namespaceprovides function objects and meta-functions corresponding to the infix operators in C++.

boost::numeric::operators namespace are additional operator overloads for some useful operations not provided by the standard library

In the boost::numeric::functional namespace are function object equivalents of the infix operators.

For example, boost::numeric::plus(a, b) is equivalent to boost::numeric::functional::plus<A, B>()(a, b), and both are equivalent to using namespace boost::numeric::operators; a + b;.


Boost.Tribool

boost::logic::tribool supports 3 states: true, false, & indeterminate. supports conversion from bool values and literals:

tribool b(true);

b = false;

b = indeterminate;

tribool b2(b);

Boost.Variant

The variant class template is a safe, generic, stack-based discriminated union container ie "multi-type, single value."

Full value semantics, including adherence to standard overload resolution rules for conversion operations.

Compile-time type-safe value visitation via boost::apply_visitor.

Run-time checked explicit value retrieval via boost::get.

Too esetoric for me to investigate further right now :)


Boost.Lexical_Cast 1.0 (stringstream wrapper)

lexical_cast<T>(S s)

evolution from unsafe and archaic standard C functions atoi/itoa family, strtol , scanf family

convenient and consistent common conversions with expression-level convenience - see also numeric_cast



Well, thats it then - enjoy !
Posted on Monday, November 17, 2014 9:46 PM C++ | Back to top


Comments on this post: C++ Boost in a Nutshell

# re: C++ Boost in a Nutshell
Requesting Gravatar...
Left by XiuSangster on Nov 18, 2014 8:46 AM

# Obat Operasi Caesar
Requesting Gravatar...
Ijin Ser gan, Untuk Yang membutuhkan Obat herbal sehabis Operasi Caesar dan Operasi lainnya , Kunjungi blogkami di https://goo.gl/JnpiJf https://goo.gl/hddCo8 https://goo.gl/4QV2o5 https://goo.gl/yyXg3y https://goo.gl/i6VIwU https://goo.gl/WtSCdz
Left by Komarudin on Oct 26, 2015 4:22 AM

# Obat Operasi caesar
Requesting Gravatar...
Beritanya Bermanfaat pak. Saya Tunggu Berita Selanjutnya http://goo.gl/UKM4yB
http://goo.gl/hcFROC
Left by Hanudin on Nov 13, 2015 8:23 AM

# Efek Jelly Gamat Gold-G
Requesting Gravatar...
Saya Tunggu berita selanjutnya gan. Efek samping Jelly Gamat Gold-G<br />
Left by Hanudin on Nov 24, 2015 8:56 AM

# Cara Mengobati rasa Sakit pengeroposan Tulang
Requesting Gravatar...

Infonya good sir, I Wait for the new Info http://goo.gl/JjAgXy
Left by Hanudin on Dec 19, 2015 4:01 AM

# Obat Sakit tulang Belakang Pasca Operasi Caesar
Requesting Gravatar...
http://goo.gl/YUdc9O
Left by Dede Hani on Jan 13, 2016 9:01 AM

# Obat Untuk Luka Tersiram Air Panas
Requesting Gravatar...
Ijin ser gan . Obat Herbal Jelly Gamat Gold-G Obat Untuk Luka Tersiram Air Panas Yang Tak Kunjung Sembuh-Sembuh. Kunjungi blognya http://goo.gl/ZyKy5c
Left by Dehan on Feb 25, 2016 3:08 AM

# Obat Tradisional Hentikan Pendarahan Rahim
Requesting Gravatar...
Thank you for the info https://goo.gl/apP3na
Left by Hanudin on Apr 06, 2016 9:29 AM

# Obat Patah Tulang
Requesting Gravatar...
Ijin Ser Gan, Obat Patah Tulang Untuk Anak klik Obat Patah Tulang Untuk Anak<br />
Left by Hanudin on Jun 24, 2016 9:31 AM

# Mengatasi Penyakit Korengan
Requesting Gravatar...
http://www.dsher-bal.com/2016/07/mengatasi-penyakit-korengan.html
http://www.dsher-bal.com/2016/05/obat-menghilangkan-nanah-dan-darah-pasca-operasi.html
Left by Hanudin on Jul 21, 2016 5:57 AM

# Obat Kulit Mudah luka
Requesting Gravatar...
Saya Tunggu Berita yang barunya gan. http://goo.gl/ALWyqF
Left by Toko Dehan on Jul 26, 2016 10:47 AM

# Bekas Operasi Yang Sudah Kering Jadi Bernanah
Requesting Gravatar...
Beritanya bermanfaat. Saya tunggu berita terbarunya , Terimakasih http://goo.gl/J25UYS http://goo.gl/Zg39u8
Left by Ds Herbal on Oct 10, 2016 5:49 AM

# Berbahayakah Luka Setelah Operasi Keluar nanah
Requesting Gravatar...
Ijin Ser Gan, info berbahaya luka bernanah, kunjungi blognya http://www.tokodehan.com/2016/11/berbahayakah-luka-setelah-operasi-keluar-nanah.html
Left by Hanudin on Nov 30, 2016 4:08 AM

# Hanudin
Requesting Gravatar...
Ijin Ser Gan, Untuk Obat Salep Penyembuh luka keluar Nanah , Klik blognya http://goo.gl/Mk5oc4
Left by Salep Penyembuh Luka on Dec 20, 2016 5:05 AM

# Obat Luka
Requesting Gravatar...
Kunjungan perdana gan. Terimakasih Untuk Beritanya Bermanfaat. Kunjungi juga blog kami http://goo.gl/c6qAXQ
Left by Hanudin on Jan 11, 2017 10:02 AM

# Obat Luka Gatal Bernanah
Requesting Gravatar...
Info Untuk Obat Herbal Luka Gatal Bernanah . Kunjungi Blognya http://obatlukagatalbernanah.blogspot.co.id/2017/06/obat-luka-gatal-bernanah.html
Left by Hisna on Jun 19, 2017 9:13 AM

# Obat Borok Di Kepala
Requesting Gravatar...
Ijin ser gan. Info untuk obat borok di kepala dengan QnC Jelly Gamat http://obatborokdikepala.blogspot.co.id/2017/08/obat-borok-di-kepala.html
Left by Barnas on Aug 09, 2017 9:34 AM

Your comment:
 (will show your gravatar)


Copyright © JoshReuben | Powered by: GeeksWithBlogs.net