The lib/misc
Directory
Namespace misc
, delivered from TC-1/2 to TC-9. Convenient C++ tools.
File: local.am (lib/misc/)
This is a Makefile configuration relative to the
lib/misc/
directory. It is responsible for the creation of thelibmisc
library containing everything exported from themisc
module, and the linkage of the directory’s unit tests in the test-suite.
File: libmisc.* (lib/misc/)
The interface of the
misc
module.
File: fwd.hh (lib/misc/)
Forward declarations for the
misc
module.
File: algorithm.* (lib/misc/)
Some syntactic sugar to look for things in STL containers.
File: concepts.* (lib/misc/)
Some useful C++
concepts
over containers & iterators.
File: contract.* (lib/misc/)
A useful improvement over
cassert
.
File: deref.* (lib/misc/)
A helper class that automatically dereferences pointers on
std::ostream
.
File: endomap.* (lib/misc/)
A renaming mapping of
std::map
, defaulting to identity: mapping a class with itself (endomorphism).
File: error.* (lib/misc/)
The class
misc::error
implements an error register. Because libraries are expected to be pure, they cannot issue error messages to the error output, nor exit with failure. One could pass call-backs (as functions or as objects) to set up error handling. Instead, we choose to register the errors in an object, and have the library functions return this register: it is up the caller to decide what to do with these errors. Note also that direct calls tostd::exit
bypass stack unwinding. In other words, withstd::exit
(instead ofthrow
) your application leaks memory.An instance of
misc:error
can be used as if it were a steam to output error messages. It also keeps the current exit status until is “triggered”, i.e., until it is thrown. Each module has its own error handler. For instance, theBinder
has anerror_
attribute, and uses it to report errors:void Binder::error(const ast::Ast& loc, const std::string& msg) { error_ << misc::error::error_type::bind << loc.location_get() << ": " << msg << std::endl; }Then the task system fetches the local error handler, and merges it into the global error handler
task_error()
(seecommon.*
). Some tasks trigger the error handler: if errors were registered, an exception is raised to exit the program cleanly. The following code demonstrates both aspects.void bindings_compute() { // bind::bind returns the local error handler. task_error() << ::bind::bind(*ast::tasks::the_program); task_error().exit_on_error(); }
File: escape.* (lib/misc/)
The file implements a means to output string while escaping non-printable characters. An exemple:
std::cout << "escape(\"\111\") = " << escape("\"\111\"") << std::endl;Understanding how
escape
works is required starting from TC-1/2.
File: file-library.* (lib/misc/)
This file provided a class to manage sets of inclusion paths. It aims to store search path and all information used for processing
import
directives.
File: graph.* (lib/misc/)
This file contains a generic implementation of oriented and undirected graphs. Understanding how
graph
works is required starting from TC-8.Graphs are implemented using the boost::Graph library.
File: indent.* (lib/misc/)
Exploiting regular
std::ostream
to produce indented output.std::cout << "Not indented"; std::cout << misc::incendl << "Indented, " << misc::decindent; std::cout << "Still indented" << misc::iendl; std::cout << "Not indented";will give
Not indented Indented, Still indented Not indented
File: lambda-visitor.* (lib/misc/)
Helper class for
std::visit
based pattern-matching with lambdas.
File: list.* (lib/misc/)
Wrappers around
misc::vector
that introduce functional-style manipulation of vectors.
File: map.* (lib/misc/)
A wrapper around
std::map
providing syntactic sugar for any mapping of types manipulation.
File: ref.* (lib/misc/)
Smart pointers implementing reference counting. This class inherits from
shared_ptr
and adds implicit constructors and cast methods.This allows creating shared pointers without using
std::make_shared
, but withnew
operator.
File: scoped-map.* (lib/misc/)
The handling of
misc::scoped_map<Key, Data>
, generic scoped map, serving as a basis for symbol tables used by theBinder
.misc::scoped_map
maps aKey
top aData
(that should ring a bell …). You are encouraged to implement something simple, based on stacks (seestd::stack
, or better yet,std::vector
) and maps (seestd::map
).It must provide this interface:
void put(const Key& key, const Data& value)
Associated value to key in the current scope.
Data get(const Key& key) const
If key was associated to some
Data
in the open scoped, return the most recent insertion. Otherwise, ifData
is a pointer type, then return the null pointer, else throw astd::range_error
. To implement this feature, see concepts. Pay close attention to the Redeclarations section of that page to help declare the constrained get method.std::ostream& dump(std::ostream& ostr) const
Send the content of this table on
ostr
in a human-readable manner, and return the stream.void scope_begin()
Open a new scope.
void scope_end()
Close the last scope, forgetting everything since the latest
scope_begin()
.
File: select-const.* (lib/misc/)
A helper to select between a non-
const
or aconst
type.
File: separator.* (lib/misc/)
A helper to output containers to
std::ostream
, with a separator between items.
File: set.* (lib/misc/)
A wrapper around
std::set
that introduce convenient operators (operator+
,operator%
and so forth).
File: singleton.* (lib/misc/)
A generic class implementing the Singleton design pattern. See refactoring.guru for more details about this design pattern.
File: symbol.* (lib/misc/)
In a program, the rule for identifiers is to be used many times: at least once for its definition, and once for each use. Just think about the number of occurrences of
size_t
in a C program for instance.To save space one keeps a single copy of each identifier. This provides additional benefits: the address of this single copy can be used as a key: comparisons (equality or order) are much faster.
The class
misc::symbol
is an implementation of this idea;misc::symbol
is based onmisc::unique
.
File: timer.* (lib/misc/)
A class that makes it possible to have timings of processes, similarly to
gcc
’s--time-report
, orbison
’s--report=time
. It is used in theTask
machinery, but can be used to provide better timings (e.g., separating the scanner from the parser).
File: unique.* (lib/misc/)
A generic class implementing the Flyweight design pattern; it maps identical objects to a unique reference. See refactoring.guru for more details about this design pattern.
File: variant.* (lib/misc/)
A wrapper over
std::variant
supporting conversion operators.
File: vector.* (lib/misc/)
A wrapper around
std::vector
that introduce convenient constructors & methods.
File: xalloc.* (lib/misc/)
Helpers used to store flags in
std::ostream
and facilitate dumping with additional parameters.
File: test-*.cc (lib/misc/)
Unit tests.