Boost

Table of Contents

1 Filesystem

Compilation flag: -lboost_filesystem -lboost_system

common usage:

#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
fs::path path("./main.cpp");
// absolute path, basically just add the prefix, but retain the ".." and "//"
fs::path abs_path = fs::absolute(path);
// absolute, follow symbol link, and remove dot and extra slashes. Will throw exception if file does not exist
fs::path con_path = fs::canonical(path);
fs::exists(path); // if path exists or not

2 boost.any

This is a class for conversion. It can

  • hold any type.
  • predicate to check the type
  • template support

2.1 Usage

#include <list>
#include <boost/any.hpp>

2.2 Convert into boost::any

Converting any type to boost::any is as simple as assignment:

std::list<boost::any> values;
int i;
boost::any to_append = i;
values.push_back(to_append);
std::string s;
values.push_back(s);
char *cp;
values.push_back(cp);
// append nothing
values.push_back(boost::any());

2.3 Checking of type

2.3.1 boost::any::type()

first, the boost::any class has a method called type():

const std::type_info & type() const;

If the instance is empty, it returns typeid(void).

any.type() == typeid(int);

2.3.2 boost::any_cast()

any_cast can be used to check if the value is of some type. When accepting a value or reference, it will throw exception on failure. When accepting a pointer, it will not throw exception, but return a pointer of NULL.

  • any_cast<T>(any);
  • any_cast<T>(&any);
template<typename T> T any_cast(any & operand);
template<typename ValueType> ValueType * any_cast(any * operand);

An example:

bool is_char_ptr(const boost::any & operand) {
  try {
    any_cast<const char *>(operand);
    return true;
  } catch(const boost::bad_any_cast &) {
    return false;
  }
}

bool is_string(const boost::any & operand) {
  return any_cast<std::string>(&operand);
}

3 program options

3.1 Usage

#include <boost/program_options.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/variables_map.hpp>
#include <boost/program_options/parsers.hpp>

namespace po = boost::program_options;

compile use -lboost_program_options flag.

3.2 construct arguments

Create some options.

  • It can have a long name and a short name
  • If no po::value specified, it does not accept arguments
  • can specify the type of value it want
  • can specify a default value

Using implicit_value(), you tell po that, it can accept 0 or 1 token. But if you use default_value(), po will throw exception if you provide no token.

po::options_description options("Arguments");
options.add_options()
  ("help,h", "produce help message") // --help, -h
  ("config,f", po::value<std::string>(), "config file")
  ("optimization", value<int>()->default_value(10), "optimization level")
  ("print,p", po::value<std::string>()->implicit_value(""), "what to be print")
;

The options can spread into multiple descriptions. This is helpful for create options that you don't want to show in help message.

po::options_description another_options("Utils");
another_options.add_options()
  ("create-tagfile", "create tag file")
;
po::options_description hidden("Hidden options");
hidden.add_options()
  ("folder", "project folder")
  ;

positional argument is those that don't require dash.

po::positional_options_description positional;
positional.add("folder", 1);

3.3 help message

Organize and print out help message:

po::options_description help_options;
help_options
  .add(options)
  .add(another_options)
;
std::cout<< m_help_options << std::endl;

3.4 Do the parsing

Put all descriptions together and do the parsing:

po::options_description cmdline_options;
cmdline_options
  .add(options)
  .add(another_options)
  .add(hidden)
;
po::variables_map vm;
po::store(po::command_line_parser(argc, argv)
          .options(m_cmdline_options) // add cmdline options
          .positional(positional)     // add positional options
          .run(),                     // run the parser
          vm
          );
po::notify(vm);

// also from a config file.
// the value stored first is prefered, so the command line options automatically overwrite config file.
std::ifstream ifs(config_file.c_str());
if (ifs) {
  po::store(po::parse_config_file(ifs, config_file_options), vm);
  notify(vm);
}

3.5 Retrieve from vm

Now the vm is ready to get data. It is extended from std::map. The value of the map is variable_value

template<typename T> T & as();
boost::any & value();

example:

vm.count(key);
vm[key].as<std::string>();
vm[key].value();

4 filesystem

4.1 Usage

#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
namespace fs = boost::filesystem;

Compile use -lboost_system -lboost_filesystem flag.

4.2 Path

These are the methods of class path. Basic construct and retrieve string:

fs::path p("/path");
p.string();
p.clear();

4.2.1 modification

append will concatenate paths by separator, but will not add if duplicate. concatenation simply concatenate.

path& operator/=(const path& p);
path& operator+=(const path& x);
  • path& replace_extension(const path& new_extension = path());
    1. will remove existing extension()
    2. iff new extension is not empty and does not start with dot, add it

4.2.2 Decomposite

All of these returns a path.

parent_path();
remove until last slash
  • /foo/bar -> /foo
  • /foo/bar/ -> /foo/bar
filename();
  • /foo/bar.txt -> bar.txt
  • /foo/bar/ -> .
stem();
iff the filename contains dot, and is not '.' or '..', remove until the last dot.
  • /foo/bar.txt -> bar
  • /foo.bar.txt -> foo.bar
extension();
WITH DOT: from last dot to the end.
  • foo.bar.txt -> .txt

4.2.3 Query

  • empty
  • is_absolute
  • is_relative

4.3 path utilities

absolute
if relative, return current path / p
canonical
it is absolute, but check to make sure the file exists, otherwise throw exception. no symbol link, no dots, no extra slashes.
current_path
current path, back to root
exists
returns whether it exists
equivalent
return true if filestatus for both path equals, and resolve to same file system entity.

4.3.1 File operations

copy

copy(path &from, path &to)
should be used, will call the other 3 based on the type
copy_directory(path &from, path &to)
only apply for directory
copy_file(path &from, path &to)
only apply for file

create & remove

create_directory(path p)
mkdir
create_directories(path p)
mkdir -p
remove(path p)
rm
remove_all(path p)
rm -r

modify

rename(path &old, path &new)
resize_file(path &p, uintmax_t new_size)
uintmax_t file_size(path &p)
return size in byte

4.3.2 predicates

is_directory(path &p)
is_regular_file(path &p)
is_symlink(path &p)
is_other(path &p)
the file exists, but is not the above three kind
is_empty(path &p)
whether the directory is empty, or the file is of size 0
4.3.2.1 Linux is file or dir
bool utils::is_file(const std::string &file) {
  struct stat sb;
  if (stat(file.c_str(), &sb) == 0 && S_ISREG(sb.st_mode)) return true;
  else return false;
}
bool utils::is_dir(const std::string &file) {
  struct stat sb;
  if (stat(file.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)) return true;
  else return false;
}

4.4 Temp Directory

temp_directory_path()
return a temp directory name suited for creation. Will throw exception if the one being returned exists, so feel free to use.
unique_path(path p="%%%%-%%%%-%%%%-%%%%")
this will receive a string contains %, and replace it with a hex number. Default is 64 bit randomness.
/**
 * create tmp dir, return it.
 * @input s /tmp/helium-XXXXXX (must have 6 X at the end.)
 */
std::string utils::create_tmp_dir(std::string s) {
  // char tmp_dir[] = "/tmp/helium-test-temp.XXXXXX";
  std::string sub = s.substr(s.find_last_not_of('X'));
  if (sub.size() !=7) return "";
  sub = sub.substr(1);
  assert(sub.size() == 6 && "tmp dir url format error!");
  if (sub.find_first_not_of('X') != std::string::npos) return "";
  char tmp_dir[s.size()+1];
  strcpy(tmp_dir, s.c_str());

  char *result = mkdtemp(tmp_dir);

  if (result == NULL) return "";
  std::string dir = tmp_dir;
  return dir;
}

4.5 Iterators

  • class directoryiterator
if (fs::is_directory(p)) {
  for (fs::directory_entry &e : fs::directory_iterator(p)) {
    e.path();
  }
}
  • class recursivedirectoryiterator
fs::path project_folder(folder);
fs::recursive_directory_iterator it(folder), eod;
BOOST_FOREACH (fs::path const & p, std::make_pair(it, eod)) {
  if (is_regular_file(p)) {
    vs.push_back(p.string());
  }
}

5 Timer

#include <boost/timer/timer.hpp>
using boost::timer::cpu_timer;
using boost::timer::cpu_times;
using boost::timer::nanosecond_type;

nanosecond_type const twenty_seconds(20 * 1000000000LL);
nanosecond_type last(0);
cpu_timer timer;
while (more_transactions) {
  process_a_transaction();
  cpu_times const elapsed_times(timer.elapsed());
  nanosecond_type const elapsed(elapsed_times.system
                                + elapsed_times.user);
  if (elapsed >= twenty_seconds) {
    last = elapsed;
  }
}

6 Algorithm

6.1 string

Header: <boost/algorithm/string/trim.hpp>

Left:

  • trim_left(seq): modify in place, all spaces
  • trim_left_if(seq, pred)
  • trim_left_copy: return a copy
  • trim_left_copy_if

Right:

  • trim_right_copy_if
  • trim_right_copy
  • trim_right_if
  • trim_right

Both:

  • trim_copy_if
  • trim_copy
  • trim_if
  • trim

7 Graph

7.1 adjacencylist

7.1.1 Member Functions

  • adjacency_list(...)
  • void clear()
  • void swap(adjacency_list& x)

7.1.2 Non-member functions

7.1.2.1 Access
  • vertices:
std::pair<vertex_iterator, vertex_iterator> vertices(const adjacency_list& g)
  • edges:
std::pair<edge_iterator, edge_iterator> edges(const adjacency_list& g)
  • adjacent_vertices:
std::pair<adjacency_iterator, adjacency_iterator> adjacent_vertices(vertex_descriptor u, const adjacency_list& g)
  • inv_adjacent_vertices:
std::pair<inv_adjacency_iterator, inv_adjacency_iterator> inv_adjacent_vertices(vertex_descriptor u, const adjacency_list& g)
  • out_edges:
std::pair<out_edge_iterator, out_edge_iterator> out_edges(vertex_descriptor u, const adjacency_list& g)
  • in_edges:
std::pair<in_edge_iterator, in_edge_iterator> in_edges(vertex_descriptor v, const adjacency_list& g)
  • source:
vertex_descriptor source(edge_descriptor e, const adjacency_list& g)
  • target:
vertex_descriptor target(edge_descriptor e, const adjacency_list& g)
  • out_degree:
degree_size_type out_degree(vertex_descriptor u, const adjacency_list& g)
  • in_degree:
degree_size_type in_degree(vertex_descriptor u, const adjacency_list& g)
  • num_vertices:
vertices_size_type num_vertices(const adjacency_list& g)
  • num_edges:
edges_size_type num_edges(const adjacency_list& g)
  • vertex:
vertex_descriptor vertex(vertices_size_type n, const adjacency_list& g)
  • edge:
std::pair<edge_descriptor, bool> edge(vertex_descriptor u, vertex_descriptor v, const adjacency_list& g)
  • edge_range:
std::pair<out_edge_iterator, out_edge_iterator> edge_range(vertex_descriptor u, vertex_descriptor v, const adjacency_list& g)
7.1.2.2 Modification
  • add_edge:
std::pair<edge_descriptor, bool> add_edge(vertex_descriptor u, vertex_descriptor v, adjacency_list& g)
  • add_edge:
std::pair<edge_descriptor, bool> add_edge(vertex_descriptor u, vertex_descriptor v, const EdgeProperties& p, adjacency_list& g)
  • remove_edge:
void remove_edge(vertex_descriptor u, vertex_descriptor v, adjacency_list& g)
  • remove_edge:
void remove_edge(edge_descriptor e, adjacency_list& g)
  • remove_edge:
void remove_edge(out_edge_iterator iter, adjacency_list& g)
  • remove_out_edge_if:
template <class Predicate> void remove_out_edge_if(vertex_descriptor u, Predicate predicate, adjacency_list& g)
  • remove_in_edge_if:
template <class Predicate> void remove_in_edge_if(vertex_descriptor v, Predicate predicate, adjacency_list& g)
  • remove_edge_if:
template <class Predicate> void remove_edge_if(Predicate predicate, adjacency_list& g)
  • add_vertex:
vertex_descriptor add_vertex(adjacency_list& g)
  • add_vertex:
vertex_descriptor add_vertex(const VertexProperties& p, adjacency_list& g)
  • clear_vertex:
void clear_vertex(vertex_descriptor u, adjacency_list& g)
  • clear_out_edges:
void clear_out_edges(vertex_descriptor u, adjacency_list& g)
  • clear_in_edges:
void clear_in_edges(vertex_descriptor u, adjacency_list& g)
  • remove_vertex:
void remove_vertex(vertex_descriptor u, adjacency_list& g)

Author: Hebi Li

Created: 2017-06-15 Thu 12:00

Validate