Awesome
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
Example usage
#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 );
}
Compile and run
prompt> g++ -Wall -I../include -o 01-basic 01-basic.cpp && 01-basic
In a nutshell
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.
License
any lite is distributed under the Boost Software License.
Dependencies
any lite has no other dependencies than the C++ standard library.
Installation
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.
Synopsis
Contents
Types and values in namespace nonstd
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> |
Interface of any lite
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 ><br>any( ValueType && value ) noexcept | move-assign from value | |
C++11 | template< class T ><br>explicit any( in_place_type_t<T>, Args&&... args ) | in-place-construct type T | |
C++11 | template< class T, class U, class... Args ><br>explicit any( in_place_type_t<T>, std::initializer_list<U> il, Args&&... args ) | in-place-construct type T | |
<C++11 | template< class ValueType ><br>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, ...><br>any & operator=( ValueType && rhs ) | (move-)assign from value | |
<C++11 | template< class ValueType ><br>any & operator=( ValueType const & rhs ) | copy-assign from value | |
Modifiers | C++11 | template< class T, class... Args ><br>void emplace( Args && ... args ) | emplace type T |
C++11 | template< class T, class U, class... Args ><br>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 |
Algorithms for any lite
Kind | Std | Function | Result |
---|---|---|---|
Create | C++11 | template< class T, class ...Args ><br>any make_any( Args&& ...args ) | in-place construct |
C++11 | template< class T, class U, class ...Args ><br>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 |
Configuration
Tweak header
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
.
Standard selection macro
-D<b>any_CPLUSPLUS</b>=199711L
Define this macro to override the auto-detection of the supported C++ standard, if your compiler does not set the __cpluplus
macro correctly.
Select std::any
or nonstd::any
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.
-D<b>any_CONFIG_SELECT_ANY</b>=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
.
Disable exceptions
-D<b>any_CONFIG_NO_EXCEPTIONS</b>=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.
Reported to work with
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++<br>(Visual Studio) | 8 (2005), 10 (2010), 11 (2012),<br>12 (2013), 14 (2015) | |
GNU/Linux | Clang/LLVM | 3.5.0 |
GCC | 4.8.4 | |
OS X | ? | ? |
Building the tests
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
.
Buck
any-lite> buck run test/
CMake
-
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 --help
for 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.
Other implementations of any
- Isabella Muerte. MNMLSTC Core (C++11).
- Kevlin Henney. Boost.Any. Safe, generic container for single values of different value types. 2001.
Notes and References
[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.
Appendix
A.1 Compile-time information
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]
.
A.2 Any lite test specification
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]