any-lite: A single-file header-only version of a C++17-like any, a type-safe container for single values of any type for C++98, C++11 and later
Contents
- Example usage
- In a nutshell
- License
- Dependencies
- Installation
- Synopsis
- Features
- Reported to work with
- Building the tests
- Other implementations of any
- Notes and references
- Appendix
#include "nonstd/any.hpp"
#include <cassert>
#include <string>
using namespace nonstd;
int main()
{
std::string hello = "hello, world";
any var;
var = 'v' ; assert( any_cast<char>( var ) == 'v' );
var = 7 ; assert( any_cast<int >( var ) == 7 );
var = 42L ; assert( any_cast<long>( var ) == 42L );
var = hello; assert( any_cast<std::string>( var ) == hello );
}prompt> g++ -Wall -I../include -o 01-basic 01-basic.cpp && 01-basic
any lite is a single-file header-only library to represent a type-safe container for single values of any type. The library aims to provide a C++17-like any for use with C++98 and later. If available, std::any is used.
Features and properties of any lite are ease of installation (single header), freedom of dependencies other than the standard library. any lite shares the approach to in-place tags with expected-lite, optional-lite and with variant-lite and these libraries can be used together.
Limitations of any lite are the absence of small-object optimization: all contained objects are dynamically allocated. Move construction, move assignment and emplacement require C++11 and are not supported when compiling under C++98.
any lite is distributed under the Boost Software License.
any lite has no other dependencies than the C++ standard library.
any lite is a single-file header-only library. Put any.hpp in the include folder directly into the project source tree or somewhere reachable from your project.
Contents
| Purpose | Type / value | Notes |
|---|---|---|
| Type-safe container | class any | |
| Error reporting | class bad_any_cast | |
| In-place construction | struct in_place_tag | |
| in_place | select type or index for in-place construction | |
| in_place_type | select type for in-place construction | |
| (variant) | in_place_index | select index for in-place construction |
| nonstd_lite_in_place_type_t( T) | macro for alias template in_place_type_t<T> | |
| (variant) | nonstd_lite_in_place_index_t( T ) | macro for alias template in_place_index_t<T> |
| Kind | Std | Method | Result |
|---|---|---|---|
| Construction | any() | default-construct | |
| any( any const & rhs ) | copy-construct from other any | ||
| C++11 | any( any && rhs ) noexcept | move-construct from other any | |
| C++11 | template< class ValueType > any( ValueType && value ) noexcept |
move-assign from value | |
| C++11 | template< class T > explicit any( in_place_type_t<T>, Args&&... args ) |
in-place-construct type T | |
| C++11 | template< class T, class U, class... Args > explicit any( in_place_type_t<T>, std::initializer_list<U> il, Args&&... args ) |
in-place-construct type T | |
| <C++11 | template< class ValueType > any( ValueType const & value ) |
copy-assign from value | |
| ~any() | destroy current object | ||
| Assignment | any & operator=( any const & rhs ) | copy-assign from other | |
| C++11 | any & operator=( any && rhs ) noexcept | move-assign from other | |
| C++11 | template< class ValueType, ...> any & operator=( ValueType && rhs ) |
(move-)assign from value | |
| <C++11 | template< class ValueType > any & operator=( ValueType const & rhs ) |
copy-assign from value | |
| Modifiers | C++11 | template< class T, class... Args > void emplace( Args && ... args ) |
emplace type T |
| C++11 | template< class T, class U, class... Args > void emplace( std::initializer_list<U> il, Args&&... args ) |
emplace type T | |
| void reset() noexcept | destroy contained object | ||
| void swap( any & rhs ) noexcept | exchange with other any | ||
| Observers | bool has_value() const noexcept | contains an object | |
| const std::type_info & type() const noexcept | Type of contained object |
| Kind | Std | Function | Result |
|---|---|---|---|
| Create | C++11 | template< class T, class ...Args > any make_any( Args&& ...args ) |
in-place construct |
| C++11 | template< class T, class U, class ...Args > any make_any( std::initializer_list<U> il, Args&& ...args ) |
in-place construct | |
| Access | T any_cast<T>( any const & ) | obtained value | |
| T any_cast<T>( any & ) | obtained value | ||
| C++11 | T any_cast<T>( any && ) | obtained value | |
| T const * any_cast<T>( any const * ) | pointer to obtained value | ||
| T * any_cast<T>( any * ) | pointer to obtained value | ||
| Swap | void swap( any & x, any & y ) | exchange contents |
If the compiler supports __has_include(), any lite supports the tweak header mechanism. Provide your tweak header as nonstd/any.tweak.hpp in a folder in the include-search-path. In the tweak header, provide definitions as documented below, like #define any_CPLUSPLUS 201103L.
-Dany_CPLUSPLUS=199711L
Define this macro to override the auto-detection of the supported C++ standard, if your compiler does not set the __cpluplus macro correctly.
At default, any lite uses std::any if it is available and lets you use it via namespace nonstd. You can however override this default and explicitly request to use std::any or any lite's nonstd::any as nonstd::any via the following macros.
-Dany_CONFIG_SELECT_ANY=any_ANY_DEFAULT
Define this to any_ANY_STD to select std::any as nonstd::any. Define this to any_ANY_NONSTD to select nonstd::any as nonstd::any. Default is undefined, which has the same effect as defining to any_ANY_DEFAULT.
-Dany_CONFIG_NO_EXCEPTIONS=0
Define this to 1 if you want to compile without exceptions. If not defined, the header tries and detect if exceptions have been disabled (e.g. via -fno-exceptions). Default is undefined.
-Dany_CONFIG_NO_NODISCARD=0
Define this to 1 if you want to compile without [[nodiscard]]. Note that the default of marking class bad_any_cast and function any_cast() with [[nodiscard]] is not part of the C++17 standard. The rationale to use [[nodiscard]] is that unnoticed discarded error values may break the error handling flow.
The table below mentions the compiler versions any lite is reported to work with.
| OS | Compiler | Versions |
|---|---|---|
| Windows | Clang/LLVM | ? |
| GCC | 5.2.0 | |
| Visual C++ (Visual Studio) |
8 (2005), 10 (2010), 11 (2012), 12 (2013), 14 (2015) |
|
| GNU/Linux | Clang/LLVM | 3.5.0 |
| GCC | 4.8.4 | |
| OS X | ? | ? |
To build the tests you need:
- Buck or CMake version 2.8.12 or later to be installed and in your PATH.
- A suitable compiler.
The lest test framework is included in the test folder.
The following steps assume that the any lite source code has been cloned into a directory named c:\any-lite.
any-lite> buck run test/
-
Create a directory for the build outputs for a particular architecture. Here we use c:\any-lite\build-win-x86-vc10.
~> cd c:\any-lite any-lite> md build-win-x86-vc10 any-lite> cd build-win-x86-vc10 -
Configure CMake to use the compiler of your choice (run
cmake --helpfor a list).any-lite\build> cmake -G "Visual Studio 10 2010" .. -
Build the test suite in the Debug configuration (alternatively use Release).
any-lite\build> cmake --build . --config Debug -
Run the test suite.
any-lite\build> ctest -V -C Debug
All tests should pass, indicating your platform is supported and you are ready to use any lite.
- Isabella Muerte. MNMLSTC Core (C++11).
- Kevlin Henney. Boost.Any. Safe, generic container for single values of different value types. 2001.
[1] CppReference. Any.
[2] ISO/IEC WG21. N4606, section 20.8 Storage for any type. July 2016.
[3] Beman Dawes and Kevlin Henney. N3508: Any Library Proposal (Revision 2). January 2013.
[4] Kevlin Henney. Boost.Any. Safe, generic container for single values of different value types. 2001.
[5] Kevlin Henney. Valued Conversions (PDF). C++ report, July, August 2000.
[6] Kevlin Henney. Substitutability. Principles, Idioms and Techniques for C++ (PDF). Presented at JaCC, Oxford, 16th September 1999.
[7] Kevlin Henney. Idioms. Breaking the Language Barrier (PDF). Presented at the ACCU's C and C++ European Developers Forum, the Oxford Union, Oxford, UK, 12th September 1998.
The version of any lite is available via tag [.version]. The following tags are available for information on the compiler and on the C++ standard library used: [.compiler], [.stdc++], [.stdlanguage] and [.stdlibrary].
any: Allows to default construct any
any: Allows to copy-construct from any
any: Allows to move-construct from any (C++11)
any: Allows to copy-construct from literal value
any: Allows to copy-construct from const value
any: Allows to copy-construct from lvalue references
any: Allows to move-construct from value (C++11)
any: Allows to in-place construct from literal value (C++11)
any: Allows to in-place copy-construct from value (C++11)
any: Allows to in-place move-construct from value (C++11)
any: Allows to in-place copy-construct from initializer-list (C++11)
any: Allows to in-place move-construct from initializer-list (C++11)
any: Allows to copy-assign from any
any: Allows to move-assign from any (C++11)
any: Allows to copy-assign from literal value
any: Allows to copy-assign from value
any: Allows to move-assign from value (C++11)
any: Allows to copy-emplace content (C++11)
any: Allows to move-emplace content (C++11)
any: Allows to copy-emplace content from intializer-list (C++11)
any: Allows to move-emplace content from intializer-list (C++11)
any: Allows to reset content
any: Allows to swap with other any (member)
any: Allows to inspect if any contains a value
any: Allows to obtain type_info of any's content
swap: Allows to swap with other any (non-member)
make_any: Allows to in-place copy-construct any from arguments (C++11)
make_any: Allows to in-place move-construct any from arguments (C++11)
make_any: Allows to in-place copy-construct any from initializer-list and arguments (C++11)
make_any: Allows to in-place move-construct any from initializer-list and arguments (C++11)
any_cast: Allows to obtain any's content by value (any const &)
any_cast: Allows to obtain any's content by value (any &)
any_cast: Allows to obtain any's content by value (any &&)
any_cast: Allows to obtain any's content by pointer (any const *)
any_cast: Allows to obtain any's content by pointer (any *)
any_cast: Throws bad_any_cast if requested type differs from content type (any const &)
any_cast: Throws bad_any_cast if requested type differs from content type (any &)
any_cast: Throws bad_any_cast if requested type differs from content type (any &&)
any_cast: Throws bad_any_cast with non-empty what()
tweak header: reads tweak header if supported [tweak]