/any-lite

any lite - A C++17-like any, a type-safe container for single values of any type for C++98, C++11 and later in a single-file header-only library

Primary LanguageC++Boost Software License 1.0BSL-1.0

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

Language License Build Status Build status Version download Conan Try it online

Contents

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 >
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
Assigment   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

Algorithms for any lite

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

Configuration macros

Standard selection macro

-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.

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.

-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.

Disable exceptions

-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.

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++
(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 ? ?

Building the tests

To build the tests you need:

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

  1. 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
    
  2. Configure CMake to use the compiler of your choice (run cmake --help for a list).

     any-lite\build> cmake -G "Visual Studio 10 2010" ..
    
  3. Build the test suite in the Debug configuration (alternatively use Release).

     any-lite\build> cmake --build . --config Debug
    
  4. 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 value
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()