Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview

Artifact ID: 0240dd03bb0a1e6cd4f115c68e1e26030c25722ec0ba4530641ffa17a83b5471
Page Name:Features
Date: 2019-01-01 13:18:10
Original User: luismachuca
Parent: 9f6f07f3214bf3fa670b4c3702fa463bb036fa0b3bc3f2c9d882db9356726e66
Content

The cxxomfort library adds various features that provide C++03, C++11 with partial support for features from later standards. For example, you can get some C++11 features in C++03, or C++14 features in C++11 (and sometimes even in C++03!).

The featureset described here is automatically included when using #include <cxxomfort/cxxomfort.hpp> or #include <cxxomfort/backports.hpp>, but you can get a more granular control of features by including specific headers. In particular, there's a .hpp header for each Standard C++ header that has backports in the library .

Base Features

This is the base feature set that is always included automatically when you use this library. Most of it involves backporting to C++03 some features from C++11. If access to only these base features is desired for more granular control, include as follows:

#include <cxxomfort/base.hpp>

The base feature set comprises:

Standard Features

This is the "normal" feature set, which basically consists of backporting or integrating features from selected C++ headers. In order to access these one can explicitly invoke cxxomfort.hpp or backports.hpp, or any of the more specific headers with the backports wanted.

#include <cxxomfort/cxxomfort.hpp> // the entire library
#include <cxxomfort/backports.hpp> // C++ backports and minor assist only

Features from:

<algorithm> -- <array> -- <cstddef> -- <cstdint> -- <cuchar> -- <forward_list> -- <functional> -- <limits> -- <memory> -- <numeric> -- <random> -- <string> -- <string_view> -- <system_error> -- <tuple> -- <typeindex> -- <type traits> -- <utility>

Other Features

The library also adds some of its own assortment of features specific to cxxomfort - as in, not part of C++ revisions or proposals.

There's also utilities not included in the normal cxxomfort distribution, called Extras.

Details

This library adds the features in a special namespace, ::cxxomfort::cxxostd. To improve portability, then the features that are present in namespace ::std in the new standard are added there via a using directive.

The library also implements some of the new keywords added in C++11, in particular static_assert.

Details of Base Features

Here follows a listing of features.

Null pointer literal

Implemented by base.hpp.

C++11 defines a "null pointer literal" as a special keyword that can be used to explicitly indicate a null pointer and its type. This allows code relying on null pointers to implement null-specific features such as function overloads, as well as avoid ambiguities due to null-to-integral promotion. In C++11, this literal is named `nullptr` and is documented here, including usage examples.

This library implements the null pointer literal in C++03 in the way recommended by the Standard (see also Meyer's implementation).

Known limitations:

  • Requires the inclusion of a header to be used.
  • Does not implement any operators beyond implicit conversion.

Static Assert

Implements: n1604, n1720 for compile-time assertions into the language.

Implemented by base.hpp.

C++11 adds the capability to perform assertions at compile time via a special keyword. This allows code to test for prerequisites at compile-time and deliver better error messages.

The compile-time assertion feature in C++11 is documented here, including usage samples.

The static_assert keyword is implemented in C++03 as a pseudo-keyword using a macro with the same syntax; however, being a macro, it has some limitations.

Known limitations:

  • Can not take arguments containing comas - for those, wrapping parentheses, a typedef or an enum declaration are required (and recommended even in C++11 mode, as they make code clearer).
  • The compiler won't be able to display the actual error message string, although it will at least point to its location (which, when using an IDE, should amount to the same effect).

Non-backport assists:

  • Starting in version 0.42): the extra pseudokeyword static_assert0 serves as a static assert without message, as per C++17/C++20.

Metaprogramming Helpers

Implementation of the helpers identity, enable_if, conditional.

Brief description:

template <typename T> struct identity {
    typedef T type;
};
template <bool If, typename T> struct enable_if {
    defined_if(If) typedef T type;
};
template <bool If, typename A, typename B> struct conditional {
    defined_if(If) typedef A type;
    defined_else() typedef B type;
};

The three are unconditionally added to namespace std.


Iterator Access Functions

Implemented by base.hpp. See also: https://en.cppreference.com/w/cpp/iterator .

The following interfaces are backported from C++11:

  • std::begin and std::end -- generically find the begin and end iterators for a container-like expression.
  • std::next and std::prev -- generically advance an iterator in forward or backward direction.

Details of Standard Features

Features from <algorithm>

#include <cxxomfort/algorithm.hpp>

The library includes some of the newer generic algorithms, backporting them to previous versions mostly C++03 and C++11. The list of features includes but is not limited to:

  • Copy algorithms copy_if, partition_copy etc - see copy.
  • minmax and minmax_element - see minmax.
  • The ..._of query-all algorithms - see all_any_none_of-
  • The C++11 permutation algorithms.
  • is_sorted.
  • The C++14 overloads for equal and mismatch taking ranges of different sizes.
  • The C++17 clamp - see clamp.
  • for_each_n - see for_each_n.

Example usage:

// external
struct is_odd_t { 
    int operator() (int) const {...} 
} is_odd:

// usage
vector<int> t, u;
...
copy_if (begin(t), end(t), back_inserter(u), is_odd);
assert (all_of(begin(u), end(u), is_odd);
u.sort();
assert (is_sorted(begin(u), end(u));

Features from <array>

#include <cxxomfort/array.hpp>

This header brings std::array, in particular if it is hidden behind eg.: "namespace tr1".


Features from <cstddef>

#include <cxxomfort/cstddef.hpp>

As a convenience for portability, the <cstddef> header for GCC is also provided separately.

This enables access to a number of features from C++ that are declared in the <cstddef> header or are "native" to the language and don't really sue a header:

  • std::nullptr_t from C++11 (see base features).
  • std::max_align_t from C++11.
  • std::byte type from C++17 - see std::byte at cppreference.

Features from <cstdint>

#include <cxxomfort/cstdint.hpp>

As a convenience for portability, the <cstdint> header for GCC is also provided separately.

This enables access to the integral type typedefs from C++11 such as uint16_t, int64_t, etc.


Features from <cuchar>

#include <cxxomfort/cuchar.hpp>

This gives access, in C++03 mode, to the "character types" close airquotes char16_t, char32_t. These are however defined as storage only, as there would be no practical way of embedding characters or character strings of these types in a C++03 source file without assistance from the lexer.


Features from <forward_list>

#include <cxxomfort/forward_list.hpp>

As a convenience for portability, the <forward_list> header is also provided separately.

This header adds barebones, mostly usable support for the "forward_list" sequence container in C++03. A forward_list<T> behaves much like a std::list, except elements are only singly linked - thus, traversal is only possible in one direction, from begin to end.

Header Synopsis:

(pending)

The implementation is fairly incomplete as of yet, and it has some differences from the standard's provided one as I found it to be faulty.

  • push_back and emplace_back members are provided.
  • size member is provided.
  • insert member taking a iterator range is provided.
  • before_begin is not provided as of yet.
  • remove,remove_if are unimplemented as of yet.
  • erase_after is unimplemented as of yet.
  • unique is unimplemented as of yet.
  • reverse,resize are unimplemented as of yet.

The transparent header <forward_list> is also provided so that code can be written in a forwards-compatible manner using a standard #include directive. See the page for details.


Features from <functional>

#include <cxxomfort/functional.hpp>

This header adds a number of utilities from <functional> as well as some minor assists. In C++03 it does require the presence of the utilities from TR1, in particular reference_wrapper, to work correctly.

  • Heterogeneous / Type-transparent functors such as improved "bit_and" and "plus" (from n3421), aka: their <void> specializations.
  • not_fn.
  • std::invoke from C++17, only for C++11 onward.
  • For incomplete functional/TR1 implementations: the family of bit_and etc functors.
  • hash<> specialization for enum types, from C++14 -- see below for "non-backports" however.

Non-backport assists:

  • A separate hash facility, cxxomfort::fix::hash is provided, that has the advantage of being more easily specializable (it can specialize on type traits, etc). By default, it forwards to std::hash.
namespace cxxomfort { namespace cxxostd { namespace fix {

template <typename T, typename If_ = void>
struct hash: public std::hash<T> {
};

} } }

Because the normal std::hash facility is not generically specializable (can only specialize for specific, named Ts), this alternative facility is used to provide in Cxxomfort features such as hash<> for enum types. As such in order to resolve those, one of the following must be done:

  • using cxxomfort::fix::hash to shadow the normal std implementation, or
  • explicitly invoking cxxomfort::fix::hash<...> where desired.

Example usages:

Heterogeneous Functors

// Generically "join" a sequence using the % operator, if so defined
class SumType;
struct Sum {
    template <typename SequenceType>
    SumType operator() (SequenceType const& ss) const {
        return accumulate (begin(vi), end(vi), modulus<void>() );
    }
};

SumType s;
vector<int> vi;
...; // add content to vi somehow
s= Sum()(vi); // <-- call does not need to be made aware of the type of vi's elements
vector<TypeWithModulus> vt;
...; // add content to vt somehow
s= Sum()(vt); // <-- call does not need to be made aware of the type of vt's elements


Features from <iterator>

#include <cxxomfort/iterator.hpp>

The header adds some features from newer <iterator> set, as well as the same base iterator features added by cxxomfort's base.hpp.

  • Nonmember "begin", "end" (already part of cxxomfort's base featureset).
  • Nonmember "cbegin", "cend" from C++14.
  • Nonmember "data", "size" and "empty" from C++17.
  • Nonmember begin, end for std::valarray<T>.

Features from <limits>

#include <cxxomfort/limits.hpp>

The library includes a special template integral_limits that extends std::numeric_limits for integral types by adding const min, max members rather than functions, so that the values can be accessed generically from C++03.

For a given integral type integral, the type cxxomfort::integral_limits<integral> inherits from std::numeric_limits<integral>, and adds the following member values:

template <typename integral> class integral_limits {
    // members from std::numeric_limits<integral>
    static const integral const_min = INTGRL_MIN; // implementation-defined
    static const integral const_max = INTGRL_MAX; // implementation-defined
    template <ushort> digits_base {
        uint value;
    };
};

For example, integral_limits<unsigned short>::const_min is equal to USHRT_MIN (which should be zero).

The const_min,const_max member variable has the same value as what is returned by the min(),max() member functions.

The digits_base member template, instantiated with an integer value, defines value as a member with the number of digits the type takes in the given base, similar to digits,digits10.


Features from <memory>

#include <cxxomfort/memory.hpp>

The library includes some features that are available via the <memory> header for the management of pointers and memory:

  • std::addressof from C++11.
  • An implementation of "alignof(T)" that redirects to the compiler specific where available (eg.: __alignof keyword in some C++03 compilers).
  • An alternative usage for alignas as a macro that uses compiler specifics.
  • std::aligned_storage (partial in C++03).
  • Barebones implementations for std::pointer_traits and std::allocator_traits to ease uniform API usage when writing eg.: containers.
  • unique_ptr backport for C++03, from Howard Hinnant.
  • make_unique from C++14.

The library implements alignof(type) by calling a compiler-specific feature, usually something like __alignof(type). For alignas(size), only implemented in GCC for the moment, __attribute__s are used.

The implementation of aligned_storage is made compiler specific and either takes advantage of a compiler-defined intrinsic (in the case of GCC, MSVC) or aligns objects to the alignment of at most the largest known alignable native member (such as long double or a member function pointer).

unique_ptr When using C++03 mode, this library implements the "unique_ptr" emulation created by Howard Hinnant. Once made available, the macro CXXOMFORT_USING_unique_ptr is defined.

Documentation on unique_ptr (external link). It is recommended to check this documentation as it provides both example usage and the rationale for usage cases.

This feature is provided only for storage, but it can't be used with the standard C++03 containers without a customized, move-emulation-aware Allocator.


Features from <numeric>

#include <cxxomfort/numeric.hpp>

The following interfaces from more advanced C++ versions are backported to previous versions:

  • iota from C++11.
  • gcd and lcm from C++17.

Non-backport assists:

  • A complimentary iota_n for symmetry with copy_n, for_each_n, etc.

Features from <random>

#include <cxxomfort/random.hpp>

As a convenience for portability, the <random> header is also provided separately.

This enables access to a number of features from later C++11 additions in C++03:

  • Renames of the random utilities in <tr1/random> that changed name in C++11 onward from early revisions in some compilers, for example std::tr1::uniform_int_distribution for std::tr1::uniform_int.
  • std::default_random_engine is defined as ranlux24_base in C++03.

Compatibility Fixes:

In specific versions of MSVC, in particular 2010, the shuffle_order_engine facility is broken (and as such knuth_b as well) in that they attempt to call their member Engine's non-member ::min/::max functions, and thus fail with the same header's linear_congruent_engine among others.

As such, cxxomfort::fix::shuffle_order_engine and cxxomfort::fix::knuth_b are provided which patch this issue in MSVC, or redirect to the normal std:: otherwise.


Features from <string>

#include <cxxomfort/string.hpp>

The following interfaces from C++11 are defined and backported to C++03 by this header:

  • to_string for the various arithmetic types.
  • strto(u)ll in versions of MSVC where they're not available under that name.

Example code:

    time_t tt= time(0);
    struct tm tx;
    localtime_r(&tt,&tx);
    using namespace cxxomfort::string; // brings variadic to_string in
    string s= to_string(tx.tm_hour, ':', setw(2), setfill('0'), tx.tm_min);
    cout<< s<< endl;

Pending:

  • to_wstring.

Features from <string_view>

#include <cxxomfort/string_view.hpp>

This header provides a backport of C++17's basic_string_view and its accessory typedefs. The interface has some minor changes compared to C++17 by necessity; in particular, cxxomfort's string_view has an array T(&)N constructor that std does not have.

Non-backport assists:

  • The function cxxomfort::view creates string_views from either std:: strings or static / literal character strings.

Features from <system_error>

#include <cxxomfort/system_error.hpp>

The following interfaces from C++11 are defined and backported to C++03 by this header:

  • The error_category facility and the assistant functions generic_error_category() and system_error_category().
  • The error_code facility and the assistant functions such as make_error_code.
  • The errc scoped enumeration.

Compatibility Fixes:

MSVC 2010 implements the header wrong, setting std::errc up as a namespace rather than a type and thus making impossible to compile code that uses variables of errc type or uses the type in signatures.

As such cxxomfort provides cxxomfort::fix::errc that patches as an actual type in MSVC 2010, or mirrors std::errc otherwise.

Non-backport Assists:

On its own the header also provides the functionto_errc.


Features from <tuple>

#include <cxxomfort/tuple.hpp>

The following interfaces from more advanced C++ versions are backported here:

  • get<Type>(tuple) - get a tuple's element by type (see: for an example).
  • apply(functor,tuple) - invoke a functoid using a tuple as an unpacked argument list - see: cppreference documentation.
  • make_from_tuple<T> from C++17 - create an object using a tuple as constructor arguments - see:cppreference documentation.

Features from <typeindex>

#include <cxxomfort/typeindex.hpp>

Features from <type_traits>

#include <cxxomfort/type_traits.hpp>

Various interfaces from C++'s <type_traits> header are ported here to previous versions:

  • is_lvalue_reference and is_rvalue_reference mapped from C++11 to C++03.
  • is_null_pointer from C++14 to previous Standards.
  • triviality traits (is_trivially_xxxx) for C++03.
  • void_t, make_void from C++17 to previous Standards.
  • type_identity from C++17. ref.
  • bool_constant from C++17. ref.
  • endian for endianness detection, from C++17. https://en.cppreference.com/w/cpp/types/endian|ref].
  • Others.

Features from <utility>

#include <cxxomfort/cstddef.hpp>

This header provides a number of utilities:

  • declval to provide pseudovariables in unevaluated contexts, from C++11.
  • exchange for pushing-in new values for variables, from C++14.
  • as_const helper for const_casts, from C++17.
  • An implementation of integer_sequence and index_sequence for C++11 only.
  • The type assists in_place_t and in_place_type_t.