This C++20 library provides some general useful building blocks and integrates with Google's Abseil library.
The library is tested with Clang (16+) and GCC (12+) on Ubuntu and MacOS (arm) using continuous integration: .
- Config
namespace mbo::config- mbo/config:config_cc, mbo/config/config.h
- Custom Bazel flag
--//mbo/config:limited_ordered_max_unroll_capacitywhich controls the maximum unroll size forLimitedOrderedand thusLimitedMapandLimitedSet. - Custom Bazel flag
--//mbo/config:require_throwswhich controls whetherMBO_CONFIG_REQUIREthrow exceptions or use crash logging (the defaultFalseor0). This mostly affects containers.
- Custom Bazel flag
- mbo/config:require_cc, mbo/config/require.h
- Marcos
MBO_CONFIG_REQUIRE(condition, message)which allows to check aconditionand either throw an exception or crash with Abseil FATAL logging. The behavior is controlled by--//mbo/config:require_throws.
- Marcos
- Container
namespace mbo::container- mbo/container:any_scan_cc, mbo/container/any_scan.h
- class
AnyScan: A container type independent iteration view - or scan over the container. - class
ConstScan: A container type independent iteration view for const value_types. - class
ConvertingScan: A container scanner that allows for conversions. - function
MakeAnyScan: Helper function to createAnyScaninstances. - function
MakeConstScan: Helper function to createConstScaninstances. - function
MakeConvertingScan: Helper function to createConvertingScaninstances.
- class
- mbo/container:convert_container_cc, mbo/container/convert_container.h
- conversion struct
ConvertContainersimplifies copying containers to value convertible containers.
- conversion struct
- mbo/container:limited_map_cc, mbo/container/limited_map.h
- class
LimitedMap: A space limited, constexpr compliantmap.
- class
- mbo/container:limited_options_cc, mbo/container/limited_options.h
- class
LimitedOptions: A compile time configuration option forLimitedSetandLimitedMap.
- class
- mbo/container:limited_set_cc, mbo/container/limited_set.h
- class
LimitedSet: A space limited, constexpr compliantset.
- class
- mbo/container:limited_vector_cc, mbo/container/limited_vector.h
- class
LimitedVector: A space limited, constexpr compliantvector.
- class
- Diff
namespace mbo::diff- mbo/diff:dff_cc, mbo/diff/diff.h
- class
Diff: A class that implements unified-diffing.
- class
- mbo/diff
- binary
unfied_diff: A binary that performs a unified-diff on two files.
- binary
- mbo/diff:diff_bzl, mbo/diff/diff.bzl
- bzl-macro
difftest: A test rule that compares an output versus a golden file.
- bzl-macro
- Files
namespace mbo::files- mbo/file:artefact_cc, mbo/file/artefact.h
- struct
Artefact: Holds information about a file (its data content, name, and modified time).
- struct
- mbo/file:file_cc, mbo/file/file.h
- function
GetContents: Reads a file and returns its contents or an absl::Status error. - function
GetMTime: Returns the last update/modified time of a file or an absl::Status error. - function
GetMaxLines: Reads at most given number of text lines from a file or returns absl::Status error. - function
IsAbsolutePath: Returns whether a given path is absolute. - function
JoinPaths: Join multiple path elements. - function
JoinPathsRespectAbsolute: Join multiple path elements respecting absolute path elements. - function
NormalizePath: Normalizes a path. - function
Readable: Returns whether a file is readable or an absl::Status error. - function
SetContents: Writes contents to a file.
- function
- mbo/file:glob_cc, mbo/file/glob.h
- struct
Glob2Re2Options: Control conversion of a glob pattern into a RE2 pattern. - struct
GlobEntry: Stores data for a single globbed entry (file, dir, etc.). - struct
GlobOptions: Options for functionsGlob2Re2andGlob2Re2Expression. - enum
GlobEntryAction: Allows GlobEntryFunc to control further glob progression. - type
GlobEntryFunc: Callback for acceptable glob entries. - function
GlobRe2: Performs recursive glob functionality using a RE2 pattern. - function
Glob: Performs recursive glob functionality using afnmatchstyle pattern. - function
GlobSplit: Splits a pattern into root and pattern parts. - program
glob: A recursive glob, seeglob --help.
- struct
- mbo/file/ini:ini_file_cc, mbo/file/ini/ini_file.h
- class
IniFile: A simple INI file reader.
- class
- Hash
namespace mbo::hash- mbo/hash:hash_cc, mbo/hash/hash.h
- function
simple::GetHash(std::string_view): A constexpr capable hash function.
- function
- Log
namespace mbo::log- mbo/log:demangle_cc, mbo/log/demangle.h
- functions
Demangleto log de-mangled typeid names.
- functions
- mbo/log:log_timing_cc, mbo/log/log_timing.h
- functoin
LogTiming([args])a simple timing logger.
- functoin
- Mope
namespace mbo::mope- The
MOPEtemplating engine. Runbazel run //mbo/mope -- --helpfor detailed documentation. - mbo/mope
- binary
mope.
- binary
- mbo/mope:mope_cc, mbo/mope/mope.h
- class
Template: The mope template engine and data holder.
- class
- mbo/mope:ini_cc, mbo/mope/ini.h
- function
ReadIniToTemplate: Helper to initialize a mope Template from an INI file.
- function
- mbo/mope:mope_bzl, mbo/mope/mope.bzl
- bzl-rule
mope: A rule that expands a mope template file. - bzl-macro
mope_test: A test rule that compares mope template expansion against golden files. This supportsclang-formatand thus can be used for source-code generation and verification.
- bzl-rule
- Status
namespace mbo::status- mbo/status:status_builder_cc, mbo/status/status_builder.h
- class
StatusBuilderwhich allows to extend the message of anabsl::Status.
- class
- mbo/status:status_cc, mbo/status/status.h
- function
GetStatusallows to convert types to anabsl::Status.
- function
- mbo/status:status_macros_cc, mbo/status/status_macros.h
- macro
MBO_ASSIGN_OR_RETURN: Macro that simplifies handling functions returningabsl::StatusOr<T>. - macro
MBO_MOVE_TO_OR_RETURN: Macro that simplifies handling functions returningabsl::StatusOr<T>where the result requires commas, in particular structured bindings. - macro
MBO_RETURN_IF_ERROR: Macro that simplifies handling functions returningabsl::Statusorabsl::StausOr<T>.
- macro
- Strings
namespace mbo::strings- mbo/strings:indent_cc, mbo/strings/indent.h
- function
DropIndent: Converts a raw-string text block as if it had no indent. - function
DropIndentAndSplit: Variant ofDropIndentthat returns the result as lines.
- function
- mbo/strings:numbers_cc, mbo/strings/numbers.h
- function
BigNumber: Convert integral number to string with thousands separator. - function
BigNumberLen: Calculate required string length forBigNumer.
- function
- mbo/strings:parse_cc, mbo/strings/parse.h
- function
ParseString: Parses strings respecting C++ and custom escapes as well as quotes (all configurable). - function
ParseStringList: Parses and splits strings respecting C++ and custom escapes as well as quotes (all configurable).
- function
- mbo/strings:split_cc, mbo/strings/split.h
- struct
AtLast: Allows `absl::StrSplit' to split on the last occurrence of a separator.
- struct
- mbo/strings:strip_cc, mbo/strings/strip.h
- function
ConsumePrefix: Removes a prefix from astd::string(likeabsl::ConsumePrefix). - function
ConsumeSuffix: Removes a suffix from astd::string(likeabsl::ConsumeSuffix). - function
StripPrefix: Removes a prefix from astd::string&&(likeabsl::StripPrefix). - function
StripSuffix: Removes a suffix from astd::string&&(likeabsl::StripSuffix). - struct
StripCommentsArgs: Arguments forStripCommentsandStripLineComments. - function
StripComments: Strips comments from lines. - function
StripLineComments: Strips comments from a single line. - struct
StripParsedCommentsArgs: Arguments forStripParsedCommentsandStripParsedLineComments. - function
StripParsedComments: Strips comments from parsed lines. - function
StripLineParsedComments: Strips comments from a single parsed line.
- function
- Testing
- mbo/testing:matchers_cc, mbo/testing/matchers.h
- gmock-matcher
CapacityIswhich checks the capacity of a container. - gmock-matcher
EqualsTextwhich compares text using line by line unified text diff. - gmock-matcher
IsNulloptwhich compares its argument againsstd::nullopt. - gmock-matcher
WhenTransformedBywhich allows to compare containers after transforming them. This sometimes allows for much more concise comparisons where a golden expectation is already available that only differs in a simple transformation. - gmock-matcher-modifier
WithDropIndentwhich modifiesEqualsTextso thatDropIndentwill be applied to the expected text.
- gmock-matcher
- mbo/testing:status_cc, mbo/testing/status.h
- gmock-matcher
IsOk: Tests whether anabsl::Statusorabsl::StatusOrisabsl::OkStatus. - gmock-matcher
IsOkAndHolds: Tests anabsl::StatusOrforabsl::OkStatusand contents. - gmock-matcher
StatusIs: Tests anabsl::Statusorabsl::StatusOragainst a specific status code and message. - gmock-matcher
StatusHasPayload: Tests whether anabsl::Statusorabsl::StatusOrpayload map has any payload, a specific payload url, or a payload url with specific content. - gmock-matcher
StatusPayloadsTests whether anabsl::Statusorabsl::StatusOrpayload map matches. - macro
MBO_ASSERT_OK_AND_ASSIGN: Simplifies testing with functions that returnabsl::StatusOr<T>. - macro
MBO_ASSERT_OK_AND_MOVE_TO: Simplifies testing with functions that returnabsl::StatusOr<T>where the result requires commas, in particular structured bindings.
- gmock-matcher
- mbo/testing:matchers_cc, mbo/testing/matchers.h
- Types
namespace mbo::types- mbo/types:cases_cc, mbo/types/cases.h
- meta-type
Cases: Allows to switch types based on conditions. - meta-type
CaseIndex: Evaluates the first non zero case (1-based, 0 if all zero). - meta-type
IfThen: Helper type to generate if-thenCasestypes. - meta-type
IfElse: Helper type to generate elseCaseswhich are always true and must go last. - meta-type
IfFalseThenVoid: Helper type that can be used to skip a case. - meta-type
IfTrueThenVoid: Helper type to inject default cases and to ensure the required type expansion is always possible.
- meta-type
- mbo/types:compare_cc, mbo/types/compare.h
- function
CompareArithmeticwhich cmpares two values that are scalar-numbers (including foat/double, excluding pointers and references). - function
CompareFloatwhich can compare twofloat,doubleorlong doublevalues returningstd::strong_ordering. - function
CompareIntegralwhich compares two values that are integral-numbers (no float/double, no pointers, no references). - comparator
CompareLesswhich is compatible to std::Less but allows container optimizations. - function
CompareScalarwhich compares two values that are scalar-numbers (including float/double and pointers, excluding references). - concept
ThreeWayComparableTowhich is similar tostd::three_way_comparable_withbut we only verify thatL <=> Rcan be interpreted asCatin the presented argument order. - function
WeakToStrongwhich converts astd::weak_orderingto astd::strong_ordering.
- function
- mbo/types:container_proxy_cc, mbo/types/container_proxy.h
- struct
ContainerProxywhich allows to add container access to other types including smart pointers of containers.
- struct
- mbo/types:extend_cc, mbo/types/extend.h
- crtp-struct
Extend: Enables extending of struct/class types with basic functionality. - crtp-struct
ExtendNoDefaultLikeExtendbut without default extender functionality. - crtp-struct
ExtendNoPrintLikeExtendbut withoutPrintableandStreamableextender functionality. namespace extender- extender-struct
AbslStringify: Extender that injects functionality to make anExtended type work with abseil format/print functions. SeeStringifyfor various API extension points. - extender-struct
AbslHashable: Extender that injects functionality to make anExtended type work with abseil hashing (and alsostd::hash). - extender-struct
Comparable: Extender that injects functionality to make anExtended type comparable. All comparators will be injected:<=>,==,!=,<,<=,>,>=. - extender-struct
Printable:- Extender that injects functionality to make an
Extended type get astd::string ToString() constfunction which can be used to convert a type into astd::string. - The output is a comma separated list of field values, e.g.
{ 25, 42 }. - If available (Clang 16+) this function prints field names
{ .first = 25, .second = 42 }.
- Extender that injects functionality to make an
- extender-struct
Streamable: Extender that injects functionality to make anExtended type streamable. This allows the type to be used directly withstd::ostreams.
- extender-struct
- crtp-struct
- mbo/types:no_destruct_cc, mbo/types/no_destruct.h
- struct
NoDestruct<T>: Implements a type that allows to use any type as a static constant. - Mainly, this prevents calling the destructor and thus prevents termination issues (initialization order fiasco).
- struct
- mbo/types:opaque_cc, mbo/types/opaque.h
- struct
OpaquePtran opaque alternative tostd::unique_ptrwhich works with forward declared types. - struct
OpaqueValueanOpaquePtrwith direct access, comparison and hashing which will not allow a nullptr. - struct
OpaqueContaineranOpaqueValuewith direct container access.
- struct
- mbo/types:optional_ref_cc, mbo/types/optional_data_or_ref.h
- concept
IsOptionalDataOrRefwhich determines whether a type is aOptionalDataOrRef. - struct
OptionalDataOrRefsimilar tostd::optionalbut can holdstd::nullopt, a typeTor a referenceT&/const T&. - struct
OptionalDataOrConstRefsimilar tostd::optionalbut can holdstd::nullopt, a typeTor a const referenceconst T&.
- concept
- mbo/types:optional_ref_cc, mbo/types/optional_ref.h
- concept
IsOptionalRefwhich determines whether a type is aOptionalRef. - struct
OptionalRefsimilar tostd::optionalbut can holdstd::nulloptor a referenceT&/const T&.
- concept
- mbo/types:ref_wrap_cc, mbo/types/ref_wrap.h
- template-type
RefWrap<T>: similar tostd::reference_wrapperbut supports operators->and*.
- template-type
- mbo/types:required_cc, mbo/types/required.h
- template-type
Required<T>: similar toRefWrapbut stores the actual type (and unlikestd::optionalcannot be reset).
- template-type
- mbo/types:stringify_cc, mbo/types/stringify.h
- class
Stringifya utility to convert structs into strings. - function
StringifyWithFieldNamesa format control adapter forStringify. - struct
StringifyFieldOptionswhich controls outer and inner options (both aconst StringifyOptions&). - struct
StringifyOptionswhich can be used to controlStringifyformatting. - struct
StringifyRootOptionswhich can be used to control outer/root options for streaming/printing structs. - API extension point type
MboTypesStringifySupportwhich enablesStringifysupport even if not otherwise enabled (disables Abseil stringify support inStringify). - API extension point function
MboTypesStringifyConvert(I, T, V)allows to control conversion based on field types via a static call to the owning type, receiving the field index, the object and the field value. - API extension point type
MboTypesStringifyDisablewhich disablesStringifysupport. This allows to prevent complex classes (and more importantly fields of complex types) from being printed/streamed usingStringify - API extension point type
MboTypesStringifyDoNotPrintFieldNameswhich if present disables field names inStringify. - API extension point function
MboTypesStringifyFieldNameswhich adds field names toStringify. - API extension point function
MboTypesStringifyOptionswhich adds full format control toStringify. - API extension point functoin
MboTypesStringifyValueAccesswhich allows to replace a struct with a single value inStringifyprocessing.
- class
- mbo/types:stringify_ostream_cc, mbo/types/stringify_ostream.h
- operator
std::ostream& operator<<(std::ostream&, const MboTypesStringifySupport auto& v)- conditioanl automatic ostream support for structs usingStringify. - function
SetStringifyOstreamOutputModewhich sets global Stringify stream options by mode. - function
SetStringifyOstreamOptionswhich sets global Stringify stream options.
- operator
- mbo/types:traits_cc, mbo/types/traits.h
- concept
ConstructibleFromimplements a variant ofstd::constructible_fromthat works around its limitations to deal with array args. - concept
ConstructibleIntodetermines whether one type can be constructed from another. Similar tostd::convertible_tobut with the argument order ofstd::constructible_from. - type alias
ContainerConstIteratorValueTypereturned the value-type of the const_iterator of a container. - concept
ContainerIsForwardIteratabledetermines whether a types can be used in forward iteration. - concept
ContainerHasEmplacedetermines whether a container hasemplace. - concept
ContainerHasEmplaceBackdetermines whether a container hasemplace_back. - concept
ContainerHasInsertdetermines whether a container hasinsert. - concept
ContainerHasPushBackdetermines whether a container haspush_back. - concept
ContainerHasForwardIteratordetermines whether a container hasbegin,endandstd::forward_iteratorcompliant iterators. - concept
ContainerHasInputIteratordetermines whether a container hasbegin,endandstd::input_iteratorcompliant iterators. - type alias
GetDifferenceTypeis either set to the type'sdifference_typeorstd::ptrdiff_t. - concept
HasDifferenceTypedetermines whether a type has adifference_type. - concept
IsAggregatedetermines whether a type is an aggregate. - concept
IsArithmeticusesstd::is_arithmetic_v<T>. - concept
IsBracesConstructibleVdetermines whether a type can be constructed from given argument types. - concept
IsCharArraydetermines whether a type is achar*orchar[]related type. - concept
IsDecomposabledetermines whether a type can be used in static-bindings. - concept
IsEmptyTypedetermines whether a type is empty (callsstd::is_empty_v). - concept
IsFloatingPointdetermines whether a type is a floating point type (usesstd::floating_point). - concept
IsInitializerListdetermines whether a type is `std::initializer type. - concept
IsScalarusesstd::is_scalar_v<T>. - concept
IsOptionaldetermines whether a type is astd::optionaltype. - concept
IsPairdetermines whether a type is astd::pairtype. - concept
IsReferenceWrapperdetermines whether a type is astd::reference_wrapper. - concept
IsSameAsAnyOfwhich determines whether a type is the same as one of a list of types. Similar toIsSameAsAnyOfRawbut using exact types. The inversion is available asNotSameAsAnyOf. - concept
IsSameAsAnyOfRawwhich determines whether a type is one of a list of types. Similar toIsSameAsAnyOfbut appliesstd::remove_cvref_ton all types. The inversion is available asNotSameAsAnyOfRaw. - concept
IsScalarusesstd::is_scalar_v<T>. - concept
IsSetdetermines whether a type is astd::settype. - concept
IsSmartPtrdetermines whether a type is astd::shared_ptr,std::unique_ptrorstd::weak_ptr.- Can be extended with other smart pointers through
IsSmartPtrImpl.
- Can be extended with other smart pointers through
- concept
IsStringKeyedContainerwhich determines whether a type is a container whose elements are pairs and whose keys are convertible to a std::string_view. - concept
IsTupledetermines whether a type is astd::tupletype. - concept
IsVectordetermines whether a type is astd::vectortype.
- concept
- mbo/types:template_search_cc, mbo/types/template_search.h:
- template struct
BinarySearchimplements templated binary search algorithm. - template struct
LinearSearchimplements templated linear search algorithm. - template struct
ReverseSearchimplements templated reverse linear search algorithm. - template struct
MaxSearchimplements templated linear search for last match algorithm.
- template struct
- mbo/types:tstring_cc, mbo/types/tstring.h
- struct
tstring: Implements typetstringa compile time string-literal type. - operator
operator"" _ts: String literal support for Clang, GCC and derived compilers.
- struct
- mbo/types:tuple_cc, mbo/types/tuple.h
- template struct
TupleCatwhich concatenates tuple types.
- template struct
- mbo/types:typed_view_cc, mbo/types/typed_view.h
- template struct
TypedViewa wrapper for STL views that provides type definitions, most importantlyvalue_type. That allows such views to be used with GoogleTest container matchers.
- template struct
- mbo/types:variant_cc, mbo/types/variant.h
- concept
IsVariantdetermines whether a type is astd::varianttype. - concept
IsVariantMemberTypedetermine whether aTypeis any of the types in aVariant. - struct
Overloadedwhich implements an Overload handler forstd::visit(std::variant<...>)andstd::variant::visit.
- concept
- bzl:archive.bzl
http_archive: Simple wrapper that tests whether the archive was already loaded.github_archive: Specialized archive wrapper that supports github that supportstaggedreleases or commits.
This repository requires a C++20 compiler (in case of MacOS XCode 15 is needed). This is done so that newer features like std::source_location can be used.
The project only comes with a Bazel BUILD.bazel file and can be added to other Bazel projects.
The project is formatted with specific clang-format settings which require clang 16+ (in case of MacOs LLVM 16+ can be installed using brew). For simplicity in dev mode the project pulls the appropriate clang tools and can be compiled with those tools using bazel [build|test] --config=clang ....
Checkout Releases or use head ref as follows:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "com_helly25_mbo",
url = "https://github.com/helly25/mbo/archive/refs/heads/main.tar.gz",
# See https://github.com/helly25/mbo/releases for releases.
)
Check Releases for details. All that is needed is a bazel_dep instruction with the correct version.
bazel_dep(name = "helly25_mbo", version = "0.0.0")
Unlike the WORKSPACE installation the MODULES.bazel installation from source checkout, the above Bazel-Central-Registry installation does not provide the LLVM tools and thus does not come with its own compiler. This is due to a restriction in Bazel's ability to handle toolchains when Bazel uses MODULES (--enable_bzlmod as opposed to --enable_workspace). Nonetheless all versions, all versions can be compiled with GCC 11+, Clang 17+ on Ubuntu and MacOs as enforced by CI. Other platforms and compilers are likely to work as well. However, Windows lacks some of the necessary tools and the library as well as its build system mostly assume Unix-style file and path names. That unfortunately means that on Windows some code cannot even be built.
Presented at C++ On Sea 2024, this presentation covers the theory behind:
mbo::hash::simple::GetHash,mbo::container::LimitedVector,mbo::container::LimitedMap, andmbo::container::LimitedSet.
