Skip to content

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

License

Notifications You must be signed in to change notification settings

martinmoene/any-lite

Repository files navigation

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 Vcpkg Try it online Try it on godbolt 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
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

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

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

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

Disable [[nodiscard]]

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

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

About

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

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •