Skip to content

Commit

Permalink
Initial version
Browse files Browse the repository at this point in the history
  • Loading branch information
viniciusdesa committed Nov 6, 2019
0 parents commit cec3ca8
Show file tree
Hide file tree
Showing 33 changed files with 3,164 additions and 0 deletions.
23 changes: 23 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
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.
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# strict variant

This library was adapted from [cbeck88/strict-variant](https://github.com/cbeck88/strict-variant) to compile to Arduino/ESP32 platform.

Documentation
=============

On [Chris Beck's github pages](https://cbeck88.github.io/strict-variant/index.html).

Compiler Compatibility
======================

`strict_variant` targets the C++11 standard.

It is known to work with `gcc >= 4.8` and `clang >= 3.5`, and is tested against `MSVC 2015`.

`strict_variant` can be used as-is in projects which require `-fno-exceptions` and `-fno-rtti`.

Licensing and Distribution
==========================

**strict variant** is available under the boost software license.
56 changes: 56 additions & 0 deletions examples/StrictVariantBasic/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include <Arduino.h>
#include "strict_variant/variant.hpp"

using namespace strict_variant;

std::string getString(variant<int, std::string> v);
int getInt(variant<int, std::string> v);
void printParams(std::vector<variant<int, std::string>> params);

void setup()
{
Serial.begin(115200);

printf("Starting ...");

std::vector<variant<int, std::string>> params;

variant<int, std::string> param1;
param1 = "1031001";

variant<int, std::string> param2;
param2 = 60;

params.push_back(param1);
params.push_back(param2);

printParams(params);

while (1);
}

void loop()
{
}

void printParams(std::vector<variant<int, std::string>> params)
{
printf("Printing parameters...\n");

variant<int, std::string> param1 = params[0];
printf("Param1: %s\n", getString(param1).c_str());

variant<int, std::string> vlimCurva;
vlimCurva = params[1];
printf("Param2: %d\n", getInt(vlimCurva));
}

int getInt(variant<int, std::string> v)
{
return *(get<int>(&v));
}

std::string getString(variant<int, std::string> v)
{
return *(get<std::string>(&v));
}
23 changes: 23 additions & 0 deletions library.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "strict_variant",
"version": "1.0.0",
"description": "A realtime/embedded-friendly C++11 variant type which is never empty and prevents undesirable implicit conversions.",
"keywords": "variant, polymorphism, container, cpp11, type-safety, union",
"authors":
[
{
"name": "Vinicius de Sá",
"url": "https://github.com/xvinny",
"maintainer": true
}
],
"repository":
{
"type": "git",
"url": "https://github.com/xvinny/strict_variant.git"
},
"homepage": "https://github.com/xvinny/strict_variant",
"frameworks": [ "arduino" ],
"platforms": "*",
"examples": "examples/*/*.cpp"
}
9 changes: 9 additions & 0 deletions library.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name=strict_variant
version=1.0.0
author=Vinicius de Sá
maintainer=Vinicius de Sá
sentence=A realtime/embedded-friendly C++11 variant type which is never empty and prevents undesirable implicit conversions
paragraph=Includes an example for Arduino.
category=Other
url=https://github.com/xvinny/strict_variant
architectures=*
36 changes: 36 additions & 0 deletions src/strict_variant/alloc_variant.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// (C) Copyright 2016 - 2018 Christopher Beck

// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)

#pragma once

#include <strict_variant/alloc_wrapper.hpp>
#include <strict_variant/mpl/std_traits.hpp>
#include <strict_variant/variant.hpp>
#include <type_traits>

namespace strict_variant {

//[ strict_variant_alloc_variant
template <template <typename> class Alloc>
struct alloc_variant {

// Version of wrap_if_throwing_move which uses alloc_wrapper<_, Alloc>

template <typename T, typename = mpl::enable_if_t<std::is_nothrow_destructible<T>::value
&& !std::is_reference<T>::value>>
struct wrap_throwing_move {
using type = typename std::conditional<std::is_nothrow_move_constructible<T>::value, T,
alloc_wrapper<T, Alloc<T>>>::type;
};

template <typename T>
using wrap_throwing_move_t = typename wrap_throwing_move<T>::type;

template <typename... Ts>
using type = variant<wrap_throwing_move_t<Ts>...>;
};
//]

} // end namespace strict_variant
137 changes: 137 additions & 0 deletions src/strict_variant/alloc_wrapper.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// (C) Copyright 2016 - 2018 Christopher Beck

// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)

#pragma once

/***
* For use with strict_variant::variant
*/
#include <strict_variant/wrapper.hpp>
#include <type_traits>
#include <utility>

// #define STRICT_VARIANT_DEBUG

#ifdef STRICT_VARIANT_DEBUG
#include <cassert>

#define STRICT_VARIANT_ASSERT(X, C) \
do { \
assert((X) && C); \
} while (0)

#else // STRICT_VARIANT_DEBUG

#define STRICT_VARIANT_ASSERT(X, C) \
do { \
} while (0)

#endif // STRICT_VARIANT_DEBUG

//[ strict_variant_alloc_wrapper
namespace strict_variant {

template <typename T, typename Alloc>
class alloc_wrapper {
T * m_t;

void destroy() {
if (m_t) {
Alloc a;
m_t->~T();
a.deallocate(m_t, 1);
}
}

// To avoid doing explicit try / catch (since some projects use -fno-exceptions),
// use a function object to do initialization, which cleans up after itself in the dtor
// if initialization was unsuccessful.

struct initer {
Alloc a;
bool success;
T * m_t;

initer()
: a()
, success(false)
, m_t(nullptr) {
m_t = a.allocate(1);
}

~initer() {
if (!success) { a.deallocate(m_t, 1); }
}

template <typename... Args>
void go(Args &&... args) {
new (m_t) T(std::forward<Args>(args)...);
success = true;
}
};

template <typename... Args>
void init(Args &&... args) {
initer i;
i.go(std::forward<Args>(args)...);
m_t = i.m_t;
}

public:
typedef T value_type;

~alloc_wrapper() noexcept { this->destroy(); }

template <typename... Args>
alloc_wrapper(Args &&... args)
: m_t(nullptr) {
this->init(std::forward<Args>(args)...);
}

alloc_wrapper(alloc_wrapper & rhs)
: alloc_wrapper(static_cast<const alloc_wrapper &>(rhs)) {}

alloc_wrapper(const alloc_wrapper & rhs)
: m_t(nullptr) {
this->init(rhs.get());
}

// Pointer move
alloc_wrapper(alloc_wrapper && rhs) noexcept //
: m_t(rhs.m_t) //
{
rhs.m_t = nullptr;
}

// Not assignable, we never actually need this, and it adds complexity
// associated to lifetime of `m_t` object.
alloc_wrapper & operator=(const alloc_wrapper &) = delete;
alloc_wrapper & operator=(alloc_wrapper &&) = delete;

T & get() & {
STRICT_VARIANT_ASSERT(m_t, "Bad access!");
return *m_t;
}
const T & get() const & {
STRICT_VARIANT_ASSERT(m_t, "Bad access!");
return *m_t;
}
T && get() && {
STRICT_VARIANT_ASSERT(m_t, "Bad access!");
return std::move(*m_t);
}
};
//]

namespace detail {

template <typename T, typename A>
struct is_wrapper<alloc_wrapper<T, A>> : std::true_type {};

} // end namespace detail

} // end namespace strict_variant

#undef STRICT_VARIANT_ASSERT
Loading

0 comments on commit cec3ca8

Please sign in to comment.