Commit 6c9882c0 authored by Millian Poquet's avatar Millian Poquet

Merge branch 'feature/remove-external-code-from-batsim-repo'

parents 46ca9753 231ccbd2
......@@ -43,7 +43,8 @@ endif()
################
# Dependencies #
################
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
"${CMAKE_SOURCE_DIR}/cmake/Modules/")
## SimGrid dependency
find_package(SimGrid REQUIRED)
......@@ -76,10 +77,18 @@ include_directories(${HIREDIS_INCLUDE_DIRS})
find_package(libev REQUIRED)
include_directories(${LIBEV_INCLUDE_DIRS})
# ZeroMQ dependency
## ZeroMQ dependency
find_package(ZMQ REQUIRED)
include_directories(${ZMQ_INCLUDE_DIRS})
## Docopt dependency
find_package(docopt REQUIRED)
include_directories(${DOCOPT_INCLUDE_DIRS})
## Pugixml dependency
find_package(pugixml REQUIRED)
include_directories(${PUGIXML_INCLUDE_DIR})
##################
# Batsim version #
##################
......@@ -117,23 +126,26 @@ add_executable(batsim ${batsim_SRC})
# Libraries to link
target_link_libraries(batsim
${SimGrid_LIBRARY}
${GMP_LIBRARIES}
${Boost_FILESYSTEM_LIBRARY_DEBUG}
${Boost_LOCALE_LIBRARY_DEBUG}
${Boost_REGEX_LIBRARY_DEBUG}
${Boost_SYSTEM_LIBRARY_DEBUG}
${OPENSSL_LIBRARIES}
${REDOX_LIBRARY}
${LIBEV_LIBRARY}
${HIREDIS_LIBRARY}
${ZMQ_LIBRARIES})
${SimGrid_LIBRARY}
${GMP_LIBRARIES}
${Boost_FILESYSTEM_LIBRARY_DEBUG}
${Boost_LOCALE_LIBRARY_DEBUG}
${Boost_REGEX_LIBRARY_DEBUG}
${Boost_SYSTEM_LIBRARY_DEBUG}
${OPENSSL_LIBRARIES}
${REDOX_LIBRARY}
${LIBEV_LIBRARY}
${HIREDIS_LIBRARY}
${ZMQ_LIBRARIES}
${DOCOPT_LIBRARIES}
${PUGIXML_LIBRARY}
)
################
# Installation #
################
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/batsim
DESTINATION bin)
DESTINATION bin)
# Let's enable warnings if needed
if (enable_warnings)
......
# Try to find docopt and validate that it is installed as it should be
# Once done it will define
# - DOCOPT_FOUND
# - DOCOPT_INCLUDE_DIRS
# - DOCOPT_LIBRARIES
# We won't be using PkgConfig and maybe this should change in the future,
# all we are about to do is check if we can find the file <docopt/docopt.h> and
# the libdocopt library (static or shared we don't care)
find_path(DOCOPT_INCLUDE_DIRS docopt/docopt.h)
find_library(DOCOPT_LIBRARIES docopt)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
docopt
DEFAULT_MSG
DOCOPT_INCLUDE_DIRS
DOCOPT_LIBRARIES
)
# Find the pugixml XML parsing library.
#
# Sets the usual variables expected for find_package scripts:
#
# PUGIXML_INCLUDE_DIR - header location
# PUGIXML_LIBRARIES - library to link against
# PUGIXML_FOUND - true if pugixml was found.
find_path(PUGIXML_INCLUDE_DIR pugixml.hpp)
find_library(PUGIXML_LIBRARY pugixml)
# Support the REQUIRED and QUIET arguments, and set PUGIXML_FOUND if found.
include (FindPackageHandleStandardArgs)
find_package_handle_standard_args(pugixml DEFAULT_MSG PUGIXML_LIBRARY
PUGIXML_INCLUDE_DIR)
mark_as_advanced(PUGIXML_LIBRARY PUGIXML_INCLUDE_DIR)
# Compiled Object files
*.slo
*.lo
*.o
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Compiled Static libraries
*.lai
*.la
*.a
# Compiled examples, as per docs
example
naval_fate
run_testcase
run_testcase.exe
# CMake temporary files
CMakeCache.txt
CMakeFiles
CPackConfig.cmake
CPackSourceConfig.cmake
Makefile
cmake_install.cmake
docopt-config-version.cmake
# Files configured by CMake
run_tests
language: cpp
sudo: false # Use the new container infrastructure
matrix:
include:
- os: linux
env:
- COMPILER=g++-5 STDLIB=libc++
addons:
apt:
sources: ['ubuntu-toolchain-r-test', 'george-edison55-precise-backports']
packages: ["g++-5", "cmake-data", "cmake"]
- os: linux
env:
- COMPILER=g++-4.8 USE_BOOST_REGEX=ON
addons:
apt:
sources: ['ubuntu-toolchain-r-test', 'george-edison55-precise-backports', 'boost-latest']
packages: ["g++-4.8", "cmake-data", "cmake", "libboost-regex1.55-dev"]
- os: linux
env:
- COMPILER=clang++-3.6 STDLIB=libc++
addons:
apt:
sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-precise-3.6', 'george-edison55-precise-backports']
packages: ["clang-3.6", "cmake-data", "cmake"]
- os: linux
env:
- COMPILER=clang++-3.7 STDLIB=libc++
addons:
apt:
sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-precise-3.7', 'george-edison55-precise-backports']
packages: ["clang-3.7", "cmake-data", "cmake"]
- os: osx
osx_image: xcode6.4
env:
- COMPILER=clang++ V='Apple LLVM 6.4'
- COMPILER=clang++ V='Apple LLVM 6.4' WITH_CPP14=true
- os: osx
osx_image: xcode7
env:
- COMPILER=clang++ V='Apple LLVM 7.0'
- COMPILER=clang++ V='Apple LLVM 7.0' WITH_CPP14=true
before_install:
- |
if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
brew rm --force cmake && brew install cmake
fi
- CMAKE_CXX_FLAGS+=" -Wall"
- if [[ "${WITH_CPP14}" == "true" ]]; then CMAKE_OPTIONS+=" -DCMAKE_CXX_STANDARD=14"; fi
- |
if [[ "${USE_BOOST_REGEX}" == "ON" ]]; then
CMAKE_OPTIONS+=" -DUSE_BOOST_REGEX=ON"
CMAKE_OPTIONS+=" -DBoost_REGEX_LIBRARY_DEBUG=/usr/lib/x86_64-linux-gnu/libboost_regex.so.1.55.0"
CMAKE_OPTIONS+=" -DBoost_REGEX_LIBRARY_RELEASE=/usr/lib/x86_64-linux-gnu/libboost_regex.so.1.55.0"
fi
- if [[ "${STDLIB}" == "libc++" ]]; then CMAKE_CXX_FLAGS+=" -stdlib=libc++"; fi
- ${COMPILER} --version
before_script:
- rm -rf build/
- mkdir build
- cd build
- cmake -DCMAKE_CXX_COMPILER=${COMPILER} -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} -DWITH_TESTS=1 -DWITH_EXAMPLE=1 ${CMAKE_OPTIONS} ..
script:
- cmake --build .
- python run_tests
cmake_minimum_required(VERSION 3.1)
project(docopt.cpp VERSION 0.6.1)
include(GNUInstallDirs)
#============================================================================
# Settable options
#============================================================================
option(WITH_TESTS "Build tests." OFF)
option(WITH_EXAMPLE "Build example." OFF)
option(USE_BOOST_REGEX "Replace std::regex with Boost.Regex" OFF)
#============================================================================
# Internal compiler options
#============================================================================
# C++ standard
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
if(NOT CMAKE_CXX_STANDARD OR CMAKE_CXX_STANDARD LESS 11)
set(CMAKE_CXX_STANDARD 11)
endif()
# Suppression of "unknown pragma" warning on GCC
if(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-pragmas") # Code uses #pragma mark
endif()
#============================================================================
# Sources & headers
#============================================================================
set(docopt_SOURCES docopt.cpp)
set(docopt_HEADERS
docopt.h
docopt_private.h
docopt_util.h
docopt_value.h
)
#============================================================================
# Compile targets
#============================================================================
if(MSVC OR XCODE)
# MSVC requires __declspec() attributes, which are achieved via the
# DOCOPT_DLL and DOCOPT_EXPORTS macros below. Since those macros are only
# defined when building a shared library, we must build the shared and
# static libraries completely separately.
# Xcode does not support libraries with only object files as sources.
# See https://cmake.org/cmake/help/v3.0/command/add_library.html?highlight=add_library
add_library(docopt SHARED ${docopt_SOURCES} ${docopt_HEADERS})
add_library(docopt_s STATIC ${docopt_SOURCES} ${docopt_HEADERS})
else()
# If not using MSVC or Xcode, we will create an intermediate object target
# to avoid compiling the source code twice.
add_library(docopt_o OBJECT ${docopt_SOURCES} ${docopt_HEADERS})
set_target_properties(docopt_o PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
add_library(docopt SHARED $<TARGET_OBJECTS:docopt_o>)
add_library(docopt_s STATIC $<TARGET_OBJECTS:docopt_o>)
endif()
target_include_directories(docopt PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}> $<INSTALL_INTERFACE:include/docopt>)
target_include_directories(docopt_s PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}> $<INSTALL_INTERFACE:include/docopt>)
if(MSVC)
# DOCOPT_DLL: Must be specified when building *and* when using the DLL.
# That's what the "PUBLIC" means.
# DOCOPT_EXPORTS: Must use __declspec(dllexport) when building the DLL.
# "PRIVATE" means it's only defined when building the DLL.
target_compile_definitions(docopt PUBLIC DOCOPT_DLL
PRIVATE DOCOPT_EXPORTS)
endif()
if(NOT MSVC)
set_target_properties(docopt PROPERTIES OUTPUT_NAME docopt)
set_target_properties(docopt_s PROPERTIES OUTPUT_NAME docopt)
endif()
if(USE_BOOST_REGEX)
add_definitions("-DDOCTOPT_USE_BOOST_REGEX")
# This is needed on Linux, where linking a static library into docopt.so
# fails because boost static libs are not compiled with -fPIC
set(Boost_USE_STATIC_LIBS OFF)
find_package(Boost 1.53 REQUIRED COMPONENTS regex)
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries(docopt ${Boost_LIBRARIES})
if(WITH_STATIC)
target_link_libraries(docopt_s ${Boost_LIBRARIES})
endif()
endif()
#============================================================================
# Examples
#============================================================================
if(WITH_EXAMPLE)
add_executable(docopt_example examples/naval_fate.cpp)
target_link_libraries(docopt_example docopt)
endif()
#============================================================================
# Tests
#============================================================================
if(WITH_TESTS)
set(TESTPROG "${CMAKE_CURRENT_BINARY_DIR}/run_testcase")
set(TESTCASES "${PROJECT_SOURCE_DIR}/testcases.docopt")
add_executable(run_testcase run_testcase.cpp)
target_link_libraries(run_testcase docopt)
configure_file(
"${PROJECT_SOURCE_DIR}/run_tests.py"
"${CMAKE_CURRENT_BINARY_DIR}/run_tests"
ESCAPE_QUOTES
)
add_test("Testcases docopt" ${TESTPROG})
endif()
#============================================================================
# Install
#============================================================================
set(export_name "docopt-targets")
# Runtime package
install(TARGETS docopt EXPORT ${export_name} DESTINATION ${CMAKE_INSTALL_LIBDIR})
# Development package
install(TARGETS docopt_s EXPORT ${export_name} DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(FILES ${docopt_HEADERS} DESTINATION include/docopt)
# CMake Package
include(CMakePackageConfigHelpers)
write_basic_package_version_file("${PROJECT_BINARY_DIR}/docopt-config-version.cmake" COMPATIBILITY SameMajorVersion)
install(FILES docopt-config.cmake ${PROJECT_BINARY_DIR}/docopt-config-version.cmake DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/docopt")
install(EXPORT ${export_name} DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/docopt")
#============================================================================
# CPack
#============================================================================
set(CPACK_PACKAGE_NAME "docopt")
set(CPACK_DEBIAN_PACKAGE_DEPENDS "")
set(CPACK_RPM_PACKAGE_REQUIRES "")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Beautiful command line interfaces")
set(CPACK_PACKAGE_VENDOR "Jared Grubb")
set(CPACK_PACKAGE_CONTACT ${CPACK_PACKAGE_VENDOR})
set(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/README.rst")
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE-MIT")
set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
set(CPACK_DEBIAN_PACKAGE_SECTION "Development")
set(CPACK_RPM_PACKAGE_GROUP "Development/Libraries")
set(CPACK_RPM_PACKAGE_LICENSE "MIT")
set(CPACK_STRIP_FILES TRUE)
include(CPack)
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
Copyright (c) 2012 Vladimir Keleshev, <vladimir@keleshev.com>
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to
whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall
be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
This diff is collapsed.
include("${CMAKE_CURRENT_LIST_DIR}/docopt-targets.cmake")
This diff is collapsed.
//
// docopt.h
// docopt
//
// Created by Jared Grubb on 2013-11-03.
// Copyright (c) 2013 Jared Grubb. All rights reserved.
//
#ifndef docopt__docopt_h_
#define docopt__docopt_h_
#include "docopt_value.h"
#include <map>
#include <vector>
#include <string>
#ifdef DOCOPT_HEADER_ONLY
#define DOCOPT_INLINE inline
#define DOCOPT_API
#else
#define DOCOPT_INLINE
// With Microsoft Visual Studio, export certain symbols so they
// are available to users of docopt.dll (shared library). The DOCOPT_DLL
// macro should be defined if building a DLL (with Visual Studio),
// and by clients using the DLL. The CMakeLists.txt and the
// docopt-config.cmake it generates handle this.
#ifdef DOCOPT_DLL
// Whoever is *building* the DLL should define DOCOPT_EXPORTS.
// The CMakeLists.txt that comes with docopt does this.
// Clients of docopt.dll should NOT define DOCOPT_EXPORTS.
#ifdef DOCOPT_EXPORTS
#define DOCOPT_API __declspec(dllexport)
#else
#define DOCOPT_API __declspec(dllimport)
#endif
#else
#define DOCOPT_API
#endif
#endif
namespace docopt {
// Usage string could not be parsed (ie, the developer did something wrong)
struct DocoptLanguageError : std::runtime_error { using runtime_error::runtime_error; };
// Arguments passed by user were incorrect (ie, developer was good, user is wrong)
struct DocoptArgumentError : std::runtime_error { using runtime_error::runtime_error; };
// Arguments contained '--help' and parsing was aborted early
struct DocoptExitHelp : std::runtime_error { DocoptExitHelp() : std::runtime_error("Docopt --help argument encountered"){} };
// Arguments contained '--version' and parsing was aborted early
struct DocoptExitVersion : std::runtime_error { DocoptExitVersion() : std::runtime_error("Docopt --version argument encountered") {} };
/// Parse user options from the given option string.
///
/// @param doc The usage string
/// @param argv The user-supplied arguments
/// @param help Whether to end early if '-h' or '--help' is in the argv
/// @param version Whether to end early if '--version' is in the argv
/// @param options_first Whether options must precede all args (true), or if args and options
/// can be arbitrarily mixed.
///
/// @throws DocoptLanguageError if the doc usage string had errors itself
/// @throws DocoptExitHelp if 'help' is true and the user has passed the '--help' argument
/// @throws DocoptExitVersion if 'version' is true and the user has passed the '--version' argument
/// @throws DocoptArgumentError if the user's argv did not match the usage patterns
std::map<std::string, value> DOCOPT_API docopt_parse(std::string const& doc,
std::vector<std::string> const& argv,
bool help = true,
bool version = true,
bool options_first = false);
/// Parse user options from the given string, and exit appropriately
///
/// Calls 'docopt_parse' and will terminate the program if any of the exceptions above occur:
/// * DocoptLanguageError - print error and terminate (with exit code -1)
/// * DocoptExitHelp - print usage string and terminate (with exit code 0)
/// * DocoptExitVersion - print version and terminate (with exit code 0)
/// * DocoptArgumentError - print error and usage string and terminate (with exit code -1)
std::map<std::string, value> DOCOPT_API docopt(std::string const& doc,
std::vector<std::string> const& argv,
bool help = true,
std::string const& version = {},
bool options_first = false) noexcept;
}
#ifdef DOCOPT_HEADER_ONLY
#include "docopt.cpp"
#endif
#endif /* defined(docopt__docopt_h_) */
This diff is collapsed.
//
// docopt_util.h
// docopt
//
// Created by Jared Grubb on 2013-11-04.
// Copyright (c) 2013 Jared Grubb. All rights reserved.
//
#ifndef docopt_docopt_util_h
#define docopt_docopt_util_h
#if DOCTOPT_USE_BOOST_REGEX
#include <boost/regex.hpp>
namespace std {
using boost::regex;
using boost::sregex_token_iterator;
}
#else
#include <regex>
#endif
namespace {
bool starts_with(std::string const& str, std::string const& prefix)
{
if (str.length() < prefix.length())
return false;
return std::equal(prefix.begin(), prefix.end(),
str.begin());
}
std::string trim(std::string&& str,
const std::string& whitespace = " \t\n")
{
const auto strEnd = str.find_last_not_of(whitespace);
if (strEnd==std::string::npos)
return {}; // no content
str.erase(strEnd+1);
const auto strBegin = str.find_first_not_of(whitespace);
str.erase(0, strBegin);
return std::move(str);
}
std::vector<std::string> split(std::string const& str, size_t pos = 0)
{
const char* const anySpace = " \t\r\n\v\f";
std::vector<std::string> ret;
while (pos != std::string::npos) {
auto start = str.find_first_not_of(anySpace, pos);
if (start == std::string::npos) break;
auto end = str.find_first_of(anySpace, start);
auto size = end==std::string::npos ? end : end-start;
ret.emplace_back(str.substr(start, size));
pos = end;
}
return ret;
}
std::tuple<std::string, std::string, std::string> partition(std::string str, std::string const& point)
{
std::tuple<std::string, std::string, std::string> ret;
auto i = str.find(point);
if (i == std::string::npos) {
// no match: string goes in 0th spot only
} else {
std::get<2>(ret) = str.substr(i + point.size());
std::get<1>(ret) = point;
str.resize(i);
}
std::get<0>(ret) = std::move(str);
return ret;
}
template <typename I>
std::string join(I iter, I end, std::string const& delim) {
if (iter==end)
return {};
std::string ret = *iter;
for(++iter; iter!=end; ++iter) {
ret.append(delim);
ret.append(*iter);
}
return ret;
}
std::vector<std::string> regex_split(std::string const& text, std::regex const& re)
{
std::vector<std::string> ret;
for (auto it = std::sregex_token_iterator(text.begin(), text.end(), re, -1);
it != std::sregex_token_iterator();
++it) {
ret.emplace_back(*it);
}
return ret;
}
}
namespace docopt {
template <class T>
inline void hash_combine(std::size_t& seed, T const& v)
{
// stolen from boost::hash_combine
std::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
}
#endif
//
// value.h
// docopt
//
// Created by Jared Grubb on 2013-10-14.
// Copyright (c) 2013 Jared Grubb. All rights reserved.
//
#ifndef docopt__value_h_
#define docopt__value_h_
#include <string>
#include <vector>
#include <functional> // std::hash
#include <iosfwd>
namespace docopt {
/// A generic type to hold the various types that can be produced by docopt.
///
/// This type can be one of: {bool, long, string, vector<string>}, or empty.
struct value {
/// An empty value
value() {}
value(std::string);
value(std::vector<std::string>);
explicit value(bool);
explicit value(long);
explicit value(int v) : value(static_cast<long>(v)) {}
~value();
value(value const&);
value(value&&) noexcept;
value& operator=(value const&);
value& operator=(value&&) noexcept;
// Test if this object has any contents at all
explicit operator bool() const { return kind != Kind::Empty; }
// Test the type contained by this value object
bool isBool() const { return kind==Kind::Bool; }
bool isString() const { return kind==Kind::String; }
bool isLong() const { return kind==Kind::Long; }
bool isStringList() const { return kind==Kind::StringList; }
// Throws std::invalid_argument if the type does not match
bool asBool() const;
long asLong() const;
std::string const& asString() const;
std::vector<std::string> const& asStringList() const;
size_t hash() const noexcept;
// equality is based on hash-equality
friend bool operator==(value const&, value const&);
friend bool operator!=(value const&, value const&);
private:
enum class Kind {
Empty,
Bool,
Long,
String,
StringList
};
union Variant {
Variant() {}
~Variant() { /* do nothing; will be destroyed by ~value */ }
bool boolValue;
long longValue;
std::string strValue;
std::vector<std::string> strList;
};
static const char* kindAsString(Kind kind) {
switch (kind) {
case Kind::Empty: return "empty";
case Kind::Bool: return "bool";
case Kind::Long: return "long";
case Kind::String: return "string";
case Kind::StringList: return "string-list";
}
return "unknown";
}