Backport std::chrono_literals to C++11.
This commit is contained in:
parent
fd173c81cd
commit
8a902d8f66
|
@ -90,6 +90,9 @@ QT_WARNING_POP
|
||||||
|
|
||||||
#if __cplusplus >= 201402L
|
#if __cplusplus >= 201402L
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
#else
|
||||||
|
#include "../vmisc/bpstd/chrono.hpp"
|
||||||
|
using namespace bpstd::literals::chrono_literals;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
@ -358,7 +361,7 @@ VPMainWindow::VPMainWindow(const VPCommandLinePtr &cmd, QWidget *parent) :
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
std::this_thread::sleep_for(100ms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,11 +391,7 @@ VPMainWindow::VPMainWindow(const VPCommandLinePtr &cmd, QWidget *parent) :
|
||||||
|
|
||||||
if (m_cmd->IsGuiEnabled())
|
if (m_cmd->IsGuiEnabled())
|
||||||
{
|
{
|
||||||
#if __cplusplus >= 201402L
|
|
||||||
QTimer::singleShot(1s, this, &VPMainWindow::SetDefaultGUILanguage);
|
QTimer::singleShot(1s, this, &VPMainWindow::SetDefaultGUILanguage);
|
||||||
#else
|
|
||||||
QTimer::singleShot(1000, this, &VPMainWindow::SetDefaultGUILanguage);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,9 @@
|
||||||
|
|
||||||
#if __cplusplus >= 201402L
|
#if __cplusplus >= 201402L
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
#else
|
||||||
|
#include "../vmisc/bpstd/chrono.hpp"
|
||||||
|
using namespace bpstd::literals::chrono_literals;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(Q_OS_MAC)
|
#if defined(Q_OS_MAC)
|
||||||
|
@ -242,11 +245,7 @@ TMainWindow::TMainWindow(QWidget *parent)
|
||||||
|
|
||||||
if (MApplication::VApp()->IsAppInGUIMode())
|
if (MApplication::VApp()->IsAppInGUIMode())
|
||||||
{
|
{
|
||||||
#if __cplusplus >= 201402L
|
|
||||||
QTimer::singleShot(1s, this, &TMainWindow::SetDefaultGUILanguage);
|
QTimer::singleShot(1s, this, &TMainWindow::SetDefaultGUILanguage);
|
||||||
#else
|
|
||||||
QTimer::singleShot(1000, this, &TMainWindow::SetDefaultGUILanguage);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,9 @@
|
||||||
|
|
||||||
#if __cplusplus >= 201402L
|
#if __cplusplus >= 201402L
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
#else
|
||||||
|
#include "../vmisc/bpstd/chrono.hpp"
|
||||||
|
using namespace bpstd::literals::chrono_literals;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -85,11 +88,7 @@ DialogLayoutProgress::DialogLayoutProgress(QElapsedTimer timer, qint64 timeout,
|
||||||
m_progressTimer->stop();
|
m_progressTimer->stop();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
#if __cplusplus >= 201402L
|
|
||||||
m_progressTimer->start(1s);
|
m_progressTimer->start(1s);
|
||||||
#else
|
|
||||||
m_progressTimer->start(1000);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -41,6 +41,9 @@
|
||||||
|
|
||||||
#if __cplusplus >= 201402L
|
#if __cplusplus >= 201402L
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
#else
|
||||||
|
#include "../vmisc/bpstd/chrono.hpp"
|
||||||
|
using namespace bpstd::literals::chrono_literals;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
@ -93,11 +96,7 @@ void VWidgetDetails::UpdateList()
|
||||||
// The filling table is a very expensive operation. This optimization will postpone it.
|
// The filling table is a very expensive operation. This optimization will postpone it.
|
||||||
// Each time a new request happen we will wait 800 ms before calling it. If at this time a new request will arrive
|
// Each time a new request happen we will wait 800 ms before calling it. If at this time a new request will arrive
|
||||||
// we will wait 800 ms more. And so on, until nothing happens within 800ms.
|
// we will wait 800 ms more. And so on, until nothing happens within 800ms.
|
||||||
#if __cplusplus >= 201402L
|
|
||||||
m_updateListTimer->start(800ms);
|
m_updateListTimer->start(800ms);
|
||||||
#else
|
|
||||||
m_updateListTimer->start(800);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -216,6 +216,9 @@
|
||||||
|
|
||||||
#if __cplusplus >= 201402L
|
#if __cplusplus >= 201402L
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
#else
|
||||||
|
#include "../vmisc/bpstd/chrono.hpp"
|
||||||
|
using namespace bpstd::literals::chrono_literals;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QT_WARNING_PUSH
|
QT_WARNING_PUSH
|
||||||
|
@ -471,11 +474,7 @@ MainWindow::MainWindow(QWidget *parent)
|
||||||
|
|
||||||
if (VApplication::IsGUIMode())
|
if (VApplication::IsGUIMode())
|
||||||
{
|
{
|
||||||
#if __cplusplus >= 201402L
|
|
||||||
QTimer::singleShot(1s, this, &MainWindow::SetDefaultGUILanguage);
|
QTimer::singleShot(1s, this, &MainWindow::SetDefaultGUILanguage);
|
||||||
#else
|
|
||||||
QTimer::singleShot(1000, this, &MainWindow::SetDefaultGUILanguage);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2140,11 +2139,7 @@ void MainWindow::MeasurementsChanged(const QString &path)
|
||||||
{
|
{
|
||||||
m_mChanges = true;
|
m_mChanges = true;
|
||||||
m_mChangesAsked = false;
|
m_mChangesAsked = false;
|
||||||
#if __cplusplus >= 201402L
|
|
||||||
m_measurementsSyncTimer->start(1500ms);
|
m_measurementsSyncTimer->start(1500ms);
|
||||||
#else
|
|
||||||
m_measurementsSyncTimer->start(1500);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2154,11 +2149,7 @@ void MainWindow::MeasurementsChanged(const QString &path)
|
||||||
{
|
{
|
||||||
m_mChanges = true;
|
m_mChanges = true;
|
||||||
m_mChangesAsked = false;
|
m_mChangesAsked = false;
|
||||||
#if __cplusplus >= 201402L
|
|
||||||
m_measurementsSyncTimer->start(1500ms);
|
m_measurementsSyncTimer->start(1500ms);
|
||||||
#else
|
|
||||||
m_measurementsSyncTimer->start(1500);
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
21
src/libs/vmisc/bpstd/LICENSE
Normal file
21
src/libs/vmisc/bpstd/LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020 Matthew Rodusek
|
||||||
|
|
||||||
|
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.
|
935
src/libs/vmisc/bpstd/any.hpp
Normal file
935
src/libs/vmisc/bpstd/any.hpp
Normal file
|
@ -0,0 +1,935 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \file any.hpp
|
||||||
|
///
|
||||||
|
/// \brief This header provides definitions from the C++ header <any>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2020 Matthew Rodusek All rights reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef BPSTD_ANY_HPP
|
||||||
|
#define BPSTD_ANY_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include "detail/config.hpp"
|
||||||
|
#include "type_traits.hpp" // enable_if_t, is_*
|
||||||
|
#include "utility.hpp" // in_place_type_t, move, forward
|
||||||
|
|
||||||
|
#include <typeinfo> // std::bad_cast, std::type_info
|
||||||
|
#include <initializer_list> // std::initializer_list
|
||||||
|
#include <new> // placement-new
|
||||||
|
#include <cassert> // assert
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
|
||||||
|
|
||||||
|
namespace bpstd {
|
||||||
|
|
||||||
|
class any;
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// class : bad_any_cast
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
class bad_any_cast : public std::bad_cast
|
||||||
|
{
|
||||||
|
const char* what() const noexcept override;
|
||||||
|
};
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// class : any
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \brief An object that can hold values of any type via type-erasure
|
||||||
|
///
|
||||||
|
/// The class any describes a type-safe container for single values of any
|
||||||
|
/// type.
|
||||||
|
///
|
||||||
|
/// 1) An object of class any stores an instance of any type that satisfies
|
||||||
|
/// the constructor requirements or is empty, and this is referred to as the
|
||||||
|
/// state of the class any object. The stored instance is called the
|
||||||
|
/// contained object. Two states are equivalent if they are either both
|
||||||
|
/// empty or if both are not empty and if the contained objects are
|
||||||
|
/// equivalent.
|
||||||
|
///
|
||||||
|
/// 2) The non-member any_cast functions provide type-safe access to the
|
||||||
|
/// contained object.
|
||||||
|
///
|
||||||
|
/// This implementation uses small-buffer optimization to avoid dynamic
|
||||||
|
/// memory if the object is below a (4 * sizeof(void*))
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
class any
|
||||||
|
{
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Constructors / Destructor / Assignment
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// \brief Constructs an any instance that does not contain any value
|
||||||
|
any() noexcept;
|
||||||
|
|
||||||
|
/// \brief Moves an any instance by moving the stored underlying value
|
||||||
|
///
|
||||||
|
/// \post \p other is left valueless
|
||||||
|
///
|
||||||
|
/// \param other the other instance to move
|
||||||
|
any(any&& other) noexcept;
|
||||||
|
|
||||||
|
/// \brief Copies an any instance by copying the stored underlying value
|
||||||
|
///
|
||||||
|
/// \param other the other instance to copy
|
||||||
|
any(const any& other);
|
||||||
|
|
||||||
|
/// \brief Constructs this any using \p value for the underlying instance
|
||||||
|
///
|
||||||
|
/// \param value the value to construct this any out of
|
||||||
|
template<typename ValueType,
|
||||||
|
typename=enable_if_t<!is_same<decay_t<ValueType>,any>::value &&
|
||||||
|
is_copy_constructible<decay_t<ValueType>>::value>>
|
||||||
|
// cppcheck-suppress noExplicitConstructor
|
||||||
|
any(ValueType&& value);
|
||||||
|
|
||||||
|
/// \brief Constructs an 'any' of type ValueType by forwarding \p args to
|
||||||
|
/// its constructor
|
||||||
|
///
|
||||||
|
/// \note This constructor only participates in overload resolution if
|
||||||
|
/// ValueType is constructible from \p args
|
||||||
|
///
|
||||||
|
/// \param args the arguments to forward to ValueType's constructor
|
||||||
|
template<typename ValueType, typename...Args,
|
||||||
|
typename=enable_if_t<is_constructible<decay_t<ValueType>,Args...>::value &&
|
||||||
|
is_copy_constructible<decay_t<ValueType>>::value>>
|
||||||
|
explicit any(in_place_type_t<ValueType>, Args&&...args);
|
||||||
|
|
||||||
|
/// \brief Constructs an 'any' of type ValueType by forwarding \p args to
|
||||||
|
/// its constructor
|
||||||
|
///
|
||||||
|
/// \note This constructor only participates in overload resolution if
|
||||||
|
/// ValueType is constructible from \p args
|
||||||
|
///
|
||||||
|
/// \param il an initializer_list of arguments
|
||||||
|
/// \param args the arguments to forward to ValueType's constructor
|
||||||
|
template<typename ValueType, typename U, typename...Args,
|
||||||
|
typename=enable_if_t<is_constructible<decay_t<ValueType>,std::initializer_list<U>,Args...>::value &&
|
||||||
|
is_copy_constructible<decay_t<ValueType>>::value>>
|
||||||
|
explicit any(in_place_type_t<ValueType>,
|
||||||
|
std::initializer_list<U> il,
|
||||||
|
Args&&...args);
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
~any();
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// \brief Assigns the contents of \p other to this any
|
||||||
|
///
|
||||||
|
/// \param other the other any to move
|
||||||
|
/// \return reference to \c (*this)
|
||||||
|
any& operator=(any&& other) noexcept;
|
||||||
|
|
||||||
|
/// \brief Assigns the contents of \p other to this any
|
||||||
|
///
|
||||||
|
/// \param other the other any to copy
|
||||||
|
/// \return reference to \c (*this)
|
||||||
|
any& operator=(const any& other);
|
||||||
|
|
||||||
|
/// \brief Assigns \p value to this any
|
||||||
|
///
|
||||||
|
/// \param value the value to assign
|
||||||
|
/// \return reference to \c (*this)
|
||||||
|
template<typename ValueType,
|
||||||
|
typename=enable_if_t<!is_same<decay_t<ValueType>,any>::value &&
|
||||||
|
is_copy_constructible<decay_t<ValueType>>::value>>
|
||||||
|
any& operator=(ValueType&& value);
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Modifiers
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// \{
|
||||||
|
/// \brief Emplaces a \c ValueType into this any, destroying the previous
|
||||||
|
/// value if it contained one
|
||||||
|
///
|
||||||
|
/// \tparam ValueType the type to construct
|
||||||
|
/// \param args the arguments to forward to \c ValueType's constructor
|
||||||
|
/// \return reference to the constructed value
|
||||||
|
template<typename ValueType, typename...Args,
|
||||||
|
typename=enable_if_t<is_constructible<decay_t<ValueType>,Args...>::value &&
|
||||||
|
is_copy_constructible<decay_t<ValueType>>::value>>
|
||||||
|
decay_t<ValueType>& emplace(Args&&...args);
|
||||||
|
template<typename ValueType, typename U, typename...Args,
|
||||||
|
typename=enable_if_t<is_constructible<decay_t<ValueType>,std::initializer_list<U>,Args...>::value &&
|
||||||
|
is_copy_constructible<decay_t<ValueType>>::value>>
|
||||||
|
decay_t<ValueType>& emplace(std::initializer_list<U> il, Args&&...args );
|
||||||
|
/// \}
|
||||||
|
|
||||||
|
/// \brief Destroys the underlying stored value, leaving this any
|
||||||
|
/// empty.
|
||||||
|
void reset() noexcept;
|
||||||
|
|
||||||
|
/// \brief Swaps the contents of \c this with \p other
|
||||||
|
///
|
||||||
|
/// \post \p other contains the old contents of \c this, and \c this
|
||||||
|
/// contains the old contents of \p other
|
||||||
|
///
|
||||||
|
/// \param other the other any to swap contents with
|
||||||
|
void swap(any& other) noexcept;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Observers
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// \brief Checks whether this any contains a value
|
||||||
|
///
|
||||||
|
/// \return \c true if this contains a value
|
||||||
|
bool has_value() const noexcept;
|
||||||
|
|
||||||
|
/// \brief Gets the type_info for the underlying stored type, or
|
||||||
|
/// \c typeid(void) if \ref has_value() returns \c false
|
||||||
|
///
|
||||||
|
/// \return the typeid of the stored type
|
||||||
|
const std::type_info& type() const noexcept;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Private Static Members / Types
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Internal buffer size + alignment
|
||||||
|
static constexpr auto buffer_size = 4u * sizeof(void*);
|
||||||
|
static constexpr auto buffer_align = alignof(void*);
|
||||||
|
|
||||||
|
// buffer (for internal storage)
|
||||||
|
using internal_buffer = typename aligned_storage<buffer_size,buffer_align>::type;
|
||||||
|
|
||||||
|
union storage
|
||||||
|
{
|
||||||
|
internal_buffer internal;
|
||||||
|
void* external;
|
||||||
|
};
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// trait to determine if internal storage is required
|
||||||
|
template<typename T>
|
||||||
|
using requires_internal_storage = bool_constant<
|
||||||
|
(sizeof(T) <= buffer_size) &&
|
||||||
|
((buffer_align % alignof(T)) == 0) &&
|
||||||
|
is_nothrow_move_constructible<T>::value
|
||||||
|
>;
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct internal_storage_handler;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct external_storage_handler;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using storage_handler = conditional_t<
|
||||||
|
requires_internal_storage<T>::value,
|
||||||
|
internal_storage_handler<T>,
|
||||||
|
external_storage_handler<T>
|
||||||
|
>;
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
enum class operation
|
||||||
|
{
|
||||||
|
destroy, ///< Operation for calling the underlying's destructor
|
||||||
|
copy, ///< Operation for copying the underlying value
|
||||||
|
move, ///< Operation for moving the underlying value
|
||||||
|
value, ///< Operation for accessing the underlying value
|
||||||
|
type, ///< Operation for accessing the underlying type
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
using storage_handler_ptr = const void*(*)(operation, const storage*,const storage*);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
friend T* any_cast(any*) noexcept;
|
||||||
|
template<typename T>
|
||||||
|
friend const T* any_cast(const any*) noexcept;
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
// Private Members
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
private:
|
||||||
|
|
||||||
|
storage m_storage;
|
||||||
|
storage_handler_ptr m_storage_handler;
|
||||||
|
};
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
// non-member functions : class : any
|
||||||
|
//=========================================================================
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
// utilities
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// \brief Swaps the contents of \p lhs and \p rhs
|
||||||
|
void swap(any& lhs, any& rhs) noexcept;
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
// casts
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// \{
|
||||||
|
/// \brief Attempts to cast an any back to the underlying type T
|
||||||
|
///
|
||||||
|
/// \throw bad_any_cast if \p any is not exactly of type \p T
|
||||||
|
/// \tparam T the type to cast to
|
||||||
|
/// \return the object
|
||||||
|
template<typename T>
|
||||||
|
T any_cast(any& operand);
|
||||||
|
template<typename T>
|
||||||
|
T any_cast(any&& operand);
|
||||||
|
template<typename T>
|
||||||
|
T any_cast(const any& operand);
|
||||||
|
/// \}
|
||||||
|
|
||||||
|
/// \{
|
||||||
|
/// \brief Attempts to cast an any back to the underlying type T
|
||||||
|
///
|
||||||
|
/// \tparam T the type to cast to
|
||||||
|
/// \return pointer to the object if successfull, nullptr otherwise
|
||||||
|
template<typename T>
|
||||||
|
T* any_cast(any* operand) noexcept;
|
||||||
|
template<typename T>
|
||||||
|
const T* any_cast(const any* operand) noexcept;
|
||||||
|
/// \}
|
||||||
|
|
||||||
|
} // namespace bpstd
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// definitions : class : bad_any_cast
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
inline
|
||||||
|
const char* bpstd::bad_any_cast::what()
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
return "bad_any_cast";
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// class : any::internal_storage_handler
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct bpstd::any::internal_storage_handler
|
||||||
|
{
|
||||||
|
template<typename...Args>
|
||||||
|
static T* construct(storage& s, Args&&...args);
|
||||||
|
|
||||||
|
template<typename U, typename...Args>
|
||||||
|
static T* construct(storage& s, std::initializer_list<U> il, Args&&...args);
|
||||||
|
|
||||||
|
static void destroy(storage& s);
|
||||||
|
|
||||||
|
static const void* handle(operation op,
|
||||||
|
const storage* self,
|
||||||
|
const storage* other);
|
||||||
|
};
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// definition : class : any::internal_storage_handler
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
template<typename...Args>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
T* bpstd::any::internal_storage_handler<T>
|
||||||
|
::construct(storage& s, Args&&...args)
|
||||||
|
{
|
||||||
|
return ::new(&s.internal) T(bpstd::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
template<typename U, typename...Args>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
T* bpstd::any::internal_storage_handler<T>
|
||||||
|
::construct(storage& s, std::initializer_list<U> il, Args&&...args)
|
||||||
|
{
|
||||||
|
return ::new(&s.internal) T(il, bpstd::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
void bpstd::any::internal_storage_handler<T>
|
||||||
|
::destroy(storage& s)
|
||||||
|
{
|
||||||
|
auto* t = static_cast<T*>(static_cast<void*>(&s.internal));
|
||||||
|
t->~T();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
const void* bpstd::any::internal_storage_handler<T>
|
||||||
|
::handle(operation op,
|
||||||
|
const storage* self,
|
||||||
|
const storage* other)
|
||||||
|
{
|
||||||
|
switch (op)
|
||||||
|
{
|
||||||
|
case operation::destroy:
|
||||||
|
{
|
||||||
|
assert(self != nullptr);
|
||||||
|
BPSTD_UNUSED(other);
|
||||||
|
|
||||||
|
destroy(const_cast<storage&>(*self));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case operation::copy:
|
||||||
|
{
|
||||||
|
assert(self != nullptr);
|
||||||
|
assert(other != nullptr);
|
||||||
|
|
||||||
|
// Copy construct from the internal storage
|
||||||
|
const auto* p = reinterpret_cast<const T*>(&other->internal);
|
||||||
|
construct( const_cast<storage&>(*self), *p);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case operation::move:
|
||||||
|
{
|
||||||
|
assert(self != nullptr);
|
||||||
|
assert(other != nullptr);
|
||||||
|
|
||||||
|
// Move construct from the internal storage. '
|
||||||
|
const auto* p = reinterpret_cast<const T*>(&other->internal);
|
||||||
|
construct(const_cast<storage&>(*self), bpstd::move(*const_cast<T*>(p)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case operation::value:
|
||||||
|
{
|
||||||
|
assert(self != nullptr);
|
||||||
|
BPSTD_UNUSED(other);
|
||||||
|
|
||||||
|
// NOTE(bitwize): This seemingly arbitrary conversion is for proper
|
||||||
|
// type-safety/correctness. Otherwise, converting an aligned_storage_t*
|
||||||
|
// to void* and then to T* would violate strict-aliasing -- which
|
||||||
|
// would be undefined-behavior. Behavior is only well-defined for
|
||||||
|
// casts from void* to T* if the the void* originated from a T*.
|
||||||
|
const auto* p = reinterpret_cast<const T*>(&self->internal);
|
||||||
|
return static_cast<const void*>(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
case operation::type:
|
||||||
|
{
|
||||||
|
BPSTD_UNUSED(self);
|
||||||
|
BPSTD_UNUSED(other);
|
||||||
|
|
||||||
|
return static_cast<const void*>(&typeid(T));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// class : any::external_storage_handler
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct bpstd::any::external_storage_handler
|
||||||
|
{
|
||||||
|
template<typename...Args>
|
||||||
|
static T* construct(storage& s, Args&&...args);
|
||||||
|
|
||||||
|
template<typename U, typename...Args>
|
||||||
|
static T* construct(storage& s, std::initializer_list<U> il, Args&&...args);
|
||||||
|
|
||||||
|
static void destroy(storage& s);
|
||||||
|
|
||||||
|
static const void* handle(operation op,
|
||||||
|
const storage* self,
|
||||||
|
const storage* other);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// definition : class : any::external_storage_handler
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
template<typename...Args>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
T* bpstd::any::external_storage_handler<T>
|
||||||
|
::construct(storage& s, Args&&...args)
|
||||||
|
{
|
||||||
|
s.external = new T(bpstd::forward<Args>(args)...);
|
||||||
|
return static_cast<T*>(s.external);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
template<typename U, typename...Args>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
T* bpstd::any::external_storage_handler<T>
|
||||||
|
::construct(storage& s, std::initializer_list<U> il, Args&&...args)
|
||||||
|
{
|
||||||
|
s.external = new T(il, bpstd::forward<Args>(args)...);
|
||||||
|
return static_cast<T*>(s.external);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
void bpstd::any::external_storage_handler<T>
|
||||||
|
::destroy(storage& s)
|
||||||
|
{
|
||||||
|
delete static_cast<T*>(s.external);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
const void* bpstd::any::external_storage_handler<T>
|
||||||
|
::handle( operation op,
|
||||||
|
const storage* self,
|
||||||
|
const storage* other )
|
||||||
|
{
|
||||||
|
switch (op)
|
||||||
|
{
|
||||||
|
case operation::destroy:
|
||||||
|
{
|
||||||
|
assert(self != nullptr);
|
||||||
|
BPSTD_UNUSED(other);
|
||||||
|
|
||||||
|
destroy(const_cast<storage&>(*self));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case operation::copy:
|
||||||
|
{
|
||||||
|
assert(self != nullptr);
|
||||||
|
assert(other != nullptr);
|
||||||
|
|
||||||
|
// Copy construct from the internal storage
|
||||||
|
construct( const_cast<storage&>(*self),
|
||||||
|
*static_cast<const T*>(other->external));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case operation::move:
|
||||||
|
{
|
||||||
|
BPSTD_UNUSED(self != nullptr);
|
||||||
|
assert(other != nullptr);
|
||||||
|
|
||||||
|
const auto p = static_cast<const T*>(other->external);
|
||||||
|
// Move construct from the internal storage. '
|
||||||
|
construct(const_cast<storage&>(*self), bpstd::move(*const_cast<T*>(p)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case operation::value:
|
||||||
|
{
|
||||||
|
assert(self != nullptr);
|
||||||
|
BPSTD_UNUSED(other);
|
||||||
|
|
||||||
|
// self->external was already created as a T*; no need to cast like in
|
||||||
|
// internal.
|
||||||
|
return self->external;
|
||||||
|
}
|
||||||
|
|
||||||
|
case operation::type:
|
||||||
|
{
|
||||||
|
BPSTD_UNUSED(self);
|
||||||
|
BPSTD_UNUSED(other);
|
||||||
|
|
||||||
|
return &typeid(T);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// definitions : class : any
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Constructors / Destructor / Assignment
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
bpstd::any::any()
|
||||||
|
noexcept
|
||||||
|
: m_storage{},
|
||||||
|
m_storage_handler{nullptr}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
bpstd::any::any(any&& other)
|
||||||
|
noexcept
|
||||||
|
: m_storage{},
|
||||||
|
m_storage_handler{other.m_storage_handler}
|
||||||
|
{
|
||||||
|
if (m_storage_handler != nullptr) {
|
||||||
|
m_storage_handler(operation::move, &m_storage, &other.m_storage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
bpstd::any::any(const any& other)
|
||||||
|
: m_storage{},
|
||||||
|
m_storage_handler{nullptr}
|
||||||
|
{
|
||||||
|
|
||||||
|
if (other.m_storage_handler != nullptr) {
|
||||||
|
// Set handler after constructing, in case of exception
|
||||||
|
const auto handler = other.m_storage_handler;
|
||||||
|
|
||||||
|
handler(operation::copy, &m_storage, &other.m_storage);
|
||||||
|
m_storage_handler = handler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType, typename>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
bpstd::any::any(ValueType&& value)
|
||||||
|
: m_storage{},
|
||||||
|
m_storage_handler{nullptr}
|
||||||
|
{
|
||||||
|
// Set handler after constructing, in case of exception
|
||||||
|
using handler_type = storage_handler<decay_t<ValueType>>;
|
||||||
|
|
||||||
|
handler_type::construct(m_storage, bpstd::forward<ValueType>(value));
|
||||||
|
m_storage_handler = &handler_type::handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType, typename...Args, typename>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
bpstd::any::any(in_place_type_t<ValueType>, Args&&...args)
|
||||||
|
: m_storage{},
|
||||||
|
m_storage_handler{nullptr}
|
||||||
|
{
|
||||||
|
// Set handler after constructing, in case of exception
|
||||||
|
using handler_type = storage_handler<decay_t<ValueType>>;
|
||||||
|
|
||||||
|
handler_type::construct(m_storage, bpstd::forward<Args>(args)...);
|
||||||
|
m_storage_handler = &handler_type::handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType, typename U, typename...Args, typename>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
bpstd::any::any(in_place_type_t<ValueType>,
|
||||||
|
std::initializer_list<U> il,
|
||||||
|
Args&&...args)
|
||||||
|
: m_storage{},
|
||||||
|
m_storage_handler{nullptr}
|
||||||
|
{
|
||||||
|
// Set handler after constructing, in case of exception
|
||||||
|
using handler_type = storage_handler<decay_t<ValueType>>;
|
||||||
|
|
||||||
|
handler_type::construct(m_storage, il, bpstd::forward<Args>(args)...);
|
||||||
|
m_storage_handler = &handler_type::handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
bpstd::any::~any()
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
bpstd::any& bpstd::any::operator=(any&& other)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
|
||||||
|
if (other.m_storage_handler != nullptr) {
|
||||||
|
m_storage_handler = other.m_storage_handler;
|
||||||
|
m_storage_handler(operation::move, &m_storage, &other.m_storage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
bpstd::any& bpstd::any::operator=(const any& other)
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
|
||||||
|
if (other.m_storage_handler != nullptr) {
|
||||||
|
// Set handler after constructing, in case of exception
|
||||||
|
const auto handler = other.m_storage_handler;
|
||||||
|
|
||||||
|
handler(operation::copy, &m_storage, &other.m_storage);
|
||||||
|
m_storage_handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType, typename>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
bpstd::any& bpstd::any::operator=(ValueType&& value)
|
||||||
|
{
|
||||||
|
using handler_type = storage_handler<decay_t<ValueType>>;
|
||||||
|
|
||||||
|
reset();
|
||||||
|
|
||||||
|
handler_type::construct(m_storage, bpstd::forward<ValueType>(value));
|
||||||
|
m_storage_handler = &handler_type::handle;
|
||||||
|
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Modifiers
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template<typename ValueType, typename...Args, typename>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
bpstd::decay_t<ValueType>&
|
||||||
|
bpstd::any::emplace(Args&&...args)
|
||||||
|
{
|
||||||
|
using handler_type = storage_handler<decay_t<ValueType>>;
|
||||||
|
|
||||||
|
reset();
|
||||||
|
|
||||||
|
auto& result = *handler_type::construct(m_storage,
|
||||||
|
bpstd::forward<Args>(args)...);
|
||||||
|
m_storage_handler = &handler_type::handle;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType, typename U, typename...Args, typename>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
bpstd::decay_t<ValueType>&
|
||||||
|
bpstd::any::emplace(std::initializer_list<U> il,
|
||||||
|
Args&&...args)
|
||||||
|
{
|
||||||
|
using handler_type = storage_handler<decay_t<ValueType>>;
|
||||||
|
|
||||||
|
reset();
|
||||||
|
|
||||||
|
auto& result = *handler_type::construct(m_storage,
|
||||||
|
il,
|
||||||
|
bpstd::forward<Args>(args)...);
|
||||||
|
m_storage_handler = &handler_type::handle;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
void bpstd::any::reset()
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
if (m_storage_handler != nullptr) {
|
||||||
|
m_storage_handler(operation::destroy, &m_storage, nullptr);
|
||||||
|
m_storage_handler = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
void bpstd::any::swap(any& other)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
using std::swap;
|
||||||
|
|
||||||
|
if (m_storage_handler != nullptr && other.m_storage_handler != nullptr)
|
||||||
|
{
|
||||||
|
auto tmp = any{};
|
||||||
|
|
||||||
|
// tmp := self
|
||||||
|
tmp.m_storage_handler = m_storage_handler;
|
||||||
|
m_storage_handler(operation::move, &tmp.m_storage, &m_storage);
|
||||||
|
m_storage_handler(operation::destroy, &m_storage, nullptr);
|
||||||
|
|
||||||
|
// self := other
|
||||||
|
m_storage_handler = other.m_storage_handler;
|
||||||
|
m_storage_handler(operation::move, &m_storage, &other.m_storage);
|
||||||
|
m_storage_handler(operation::destroy, &other.m_storage, nullptr);
|
||||||
|
|
||||||
|
// other := tmp
|
||||||
|
other.m_storage_handler = tmp.m_storage_handler;
|
||||||
|
other.m_storage_handler(operation::move, &other.m_storage, &tmp.m_storage);
|
||||||
|
}
|
||||||
|
else if (other.m_storage_handler != nullptr)
|
||||||
|
{
|
||||||
|
swap(m_storage_handler, other.m_storage_handler);
|
||||||
|
|
||||||
|
// self := other
|
||||||
|
m_storage_handler(operation::move, &m_storage, &other.m_storage);
|
||||||
|
m_storage_handler(operation::destroy, &other.m_storage, nullptr);
|
||||||
|
}
|
||||||
|
else if (m_storage_handler != nullptr)
|
||||||
|
{
|
||||||
|
swap(m_storage_handler, other.m_storage_handler);
|
||||||
|
|
||||||
|
// other := self
|
||||||
|
other.m_storage_handler(operation::move, &other.m_storage, &m_storage);
|
||||||
|
other.m_storage_handler(operation::destroy, &m_storage, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Observers
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
bool bpstd::any::has_value()
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
return m_storage_handler != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
const std::type_info& bpstd::any::type()
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
if (has_value()) {
|
||||||
|
auto* p = m_storage_handler(operation::type, nullptr, nullptr);
|
||||||
|
return (*static_cast<const std::type_info*>(p));
|
||||||
|
}
|
||||||
|
return typeid(void);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// definition : non-member functions : class : any
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// utilities
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
void bpstd::swap(any& lhs, any& rhs)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
lhs.swap(rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// casts
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
T bpstd::any_cast(any& operand)
|
||||||
|
{
|
||||||
|
using underlying_type = remove_cvref_t<T>;
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
is_constructible<T, underlying_type&>::value,
|
||||||
|
"A program is ill-formed if T is not constructible from U&"
|
||||||
|
);
|
||||||
|
|
||||||
|
auto* p = any_cast<underlying_type>(&operand);
|
||||||
|
if (p == nullptr) {
|
||||||
|
throw bad_any_cast{};
|
||||||
|
}
|
||||||
|
return static_cast<T>(*p);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
T bpstd::any_cast(any&& operand)
|
||||||
|
{
|
||||||
|
using underlying_type = remove_cvref_t<T>;
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
is_constructible<T, underlying_type>::value,
|
||||||
|
"A program is ill-formed if T is not constructible from U"
|
||||||
|
);
|
||||||
|
|
||||||
|
auto* p = any_cast<underlying_type>(&operand);
|
||||||
|
if (p == nullptr) {
|
||||||
|
throw bad_any_cast{};
|
||||||
|
}
|
||||||
|
return static_cast<T>(bpstd::move(*p));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
T bpstd::any_cast(const any& operand)
|
||||||
|
{
|
||||||
|
using underlying_type = remove_cvref_t<T>;
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
is_constructible<T, const underlying_type&>::value,
|
||||||
|
"A program is ill-formed if T is not constructible from const U&"
|
||||||
|
);
|
||||||
|
|
||||||
|
const auto* p = any_cast<underlying_type>(&operand);
|
||||||
|
if (p == nullptr) {
|
||||||
|
throw bad_any_cast{};
|
||||||
|
}
|
||||||
|
return static_cast<T>(*p);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
T* bpstd::any_cast(any* operand)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
if (!operand) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (operand->type() != typeid(T)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto p = operand->m_storage_handler(any::operation::value,
|
||||||
|
&operand->m_storage,
|
||||||
|
nullptr);
|
||||||
|
return const_cast<T*>(static_cast<const T*>(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
const T* bpstd::any_cast(const any* operand)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
if (!operand) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (operand->type() != typeid(T)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* p = operand->m_storage_handler(any::operation::value,
|
||||||
|
&operand->m_storage,
|
||||||
|
nullptr);
|
||||||
|
return static_cast<const T*>(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE
|
||||||
|
|
||||||
|
#endif /* BPSTD_ANY_HPP */
|
438
src/libs/vmisc/bpstd/chrono.hpp
Normal file
438
src/libs/vmisc/bpstd/chrono.hpp
Normal file
|
@ -0,0 +1,438 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \file chrono.hpp
|
||||||
|
///
|
||||||
|
/// \brief This header provides definitions from the C++ header <chrono>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2020 Matthew Rodusek All rights reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef BPSTD_CHRONO_HPP
|
||||||
|
#define BPSTD_CHRONO_HPP
|
||||||
|
|
||||||
|
#include "detail/config.hpp"
|
||||||
|
|
||||||
|
#include <chrono> // std::chrono::duration, std::chrono::system_clock, etc
|
||||||
|
#include <cstdint> // std::int32_t
|
||||||
|
|
||||||
|
#if __cplusplus < 201402L
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
|
||||||
|
#include "../vmisc/diagnostic.h"
|
||||||
|
#endif // QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
|
||||||
|
|
||||||
|
namespace bpstd {
|
||||||
|
namespace chrono {
|
||||||
|
|
||||||
|
template <typename Rep, typename Period = std::ratio<1>>
|
||||||
|
using duration = std::chrono::duration<Rep,Period>;
|
||||||
|
|
||||||
|
template <typename Clock, typename Duration = typename Clock::duration>
|
||||||
|
using time_point = std::chrono::time_point<Clock, Duration>;
|
||||||
|
|
||||||
|
using nanoseconds = std::chrono::nanoseconds;
|
||||||
|
using microseconds = std::chrono::microseconds;
|
||||||
|
using milliseconds = std::chrono::milliseconds;
|
||||||
|
using seconds = std::chrono::seconds;
|
||||||
|
using minutes = std::chrono::minutes;
|
||||||
|
using hours = std::chrono::hours;
|
||||||
|
using days = std::chrono::duration<std::int32_t, std::ratio<86400>>;
|
||||||
|
using weeks = std::chrono::duration<std::int32_t, std::ratio<604800>>;
|
||||||
|
using months = std::chrono::duration<std::int32_t, std::ratio<2629746>>;
|
||||||
|
using years = std::chrono::duration<std::int32_t, std::ratio<31556952>>;
|
||||||
|
|
||||||
|
using steady_clock = std::chrono::steady_clock;
|
||||||
|
using system_clock = std::chrono::system_clock;
|
||||||
|
|
||||||
|
template <typename Duration>
|
||||||
|
using sys_time = time_point<system_clock, Duration>;
|
||||||
|
using sys_seconds = sys_time<seconds>;
|
||||||
|
using sys_days = sys_time<days>;
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace chrono
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// non-member functions
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Literals
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
inline namespace literals {
|
||||||
|
inline namespace chrono_literals {
|
||||||
|
|
||||||
|
constexpr auto operator""_h(unsigned long long x) -> std::chrono::hours;
|
||||||
|
constexpr auto operator""_h(long double x) -> std::chrono::duration<double, std::ratio<3600,1>>;
|
||||||
|
|
||||||
|
#if __cplusplus < 201402L
|
||||||
|
QT_WARNING_PUSH
|
||||||
|
QT_WARNING_DISABLE_CLANG("-Wuser-defined-literals")
|
||||||
|
QT_WARNING_DISABLE_GCC("-Wliteral-suffix")
|
||||||
|
|
||||||
|
// available only since C++14
|
||||||
|
constexpr auto operator""h(unsigned long long x) -> std::chrono::hours;
|
||||||
|
constexpr auto operator""h(long double x) -> std::chrono::duration<double, std::ratio<3600,1>>;
|
||||||
|
|
||||||
|
QT_WARNING_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
constexpr auto operator""_min(unsigned long long x) -> chrono::minutes;
|
||||||
|
constexpr auto operator""_min(long double x) -> chrono::duration<double, std::ratio<60>>;
|
||||||
|
|
||||||
|
#if __cplusplus < 201402L
|
||||||
|
QT_WARNING_PUSH
|
||||||
|
QT_WARNING_DISABLE_CLANG("-Wuser-defined-literals")
|
||||||
|
QT_WARNING_DISABLE_GCC("-Wliteral-suffix")
|
||||||
|
|
||||||
|
// available only since C++14
|
||||||
|
constexpr auto operator""min(unsigned long long x) -> chrono::minutes;
|
||||||
|
constexpr auto operator""min(long double x) -> chrono::duration<double, std::ratio<60>>;
|
||||||
|
|
||||||
|
QT_WARNING_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
constexpr auto operator""_s(unsigned long long x) -> chrono::seconds;
|
||||||
|
constexpr auto operator""_s(long double x) -> chrono::duration<double>;
|
||||||
|
|
||||||
|
#if __cplusplus < 201402L
|
||||||
|
QT_WARNING_PUSH
|
||||||
|
QT_WARNING_DISABLE_CLANG("-Wuser-defined-literals")
|
||||||
|
QT_WARNING_DISABLE_GCC("-Wliteral-suffix")
|
||||||
|
|
||||||
|
// available only since C++14
|
||||||
|
constexpr auto operator""s(unsigned long long x) -> chrono::seconds;
|
||||||
|
constexpr auto operator""s(long double x) -> chrono::duration<double>;
|
||||||
|
|
||||||
|
QT_WARNING_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
constexpr auto operator""_ms(unsigned long long x) -> chrono::milliseconds;
|
||||||
|
constexpr auto operator""_ms(long double x) -> chrono::duration<double, std::milli>;
|
||||||
|
|
||||||
|
#if __cplusplus < 201402L
|
||||||
|
QT_WARNING_PUSH
|
||||||
|
QT_WARNING_DISABLE_CLANG("-Wuser-defined-literals")
|
||||||
|
QT_WARNING_DISABLE_GCC("-Wliteral-suffix")
|
||||||
|
|
||||||
|
// available only since C++14
|
||||||
|
constexpr auto operator""ms(unsigned long long x) -> chrono::milliseconds;
|
||||||
|
constexpr auto operator""ms(long double x) -> chrono::duration<double, std::milli>;
|
||||||
|
|
||||||
|
QT_WARNING_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
constexpr auto operator""_us(unsigned long long x) -> chrono::microseconds;
|
||||||
|
constexpr auto operator""_us(long double x) -> chrono::duration<double, std::micro>;
|
||||||
|
|
||||||
|
#if __cplusplus < 201402L
|
||||||
|
QT_WARNING_PUSH
|
||||||
|
QT_WARNING_DISABLE_CLANG("-Wuser-defined-literals")
|
||||||
|
QT_WARNING_DISABLE_GCC("-Wliteral-suffix")
|
||||||
|
|
||||||
|
// available only since C++14
|
||||||
|
constexpr auto operator""us(unsigned long long x) -> chrono::microseconds;
|
||||||
|
constexpr auto operator""us(long double x) -> chrono::duration<double, std::micro>;
|
||||||
|
|
||||||
|
QT_WARNING_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
constexpr auto operator""_ns(unsigned long long x) -> chrono::nanoseconds;
|
||||||
|
constexpr auto operator""_ns(long double x) -> chrono::duration<double, std::nano>;
|
||||||
|
|
||||||
|
#if __cplusplus < 201402L
|
||||||
|
QT_WARNING_PUSH
|
||||||
|
QT_WARNING_DISABLE_CLANG("-Wuser-defined-literals")
|
||||||
|
QT_WARNING_DISABLE_GCC("-Wliteral-suffix")
|
||||||
|
|
||||||
|
// available only since C++14
|
||||||
|
constexpr auto operator""ns(unsigned long long x) -> chrono::nanoseconds;
|
||||||
|
constexpr auto operator""ns(long double x) -> chrono::duration<double, std::nano>;
|
||||||
|
|
||||||
|
QT_WARNING_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace chrono_literals
|
||||||
|
} // namespace literals
|
||||||
|
} // namespace bpstd
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto
|
||||||
|
bpstd::literals::chrono_literals::operator""_h(unsigned long long x) -> std::chrono::hours
|
||||||
|
{
|
||||||
|
return chrono::hours{x};
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __cplusplus < 201402L
|
||||||
|
QT_WARNING_PUSH
|
||||||
|
QT_WARNING_DISABLE_CLANG("-Wuser-defined-literals")
|
||||||
|
QT_WARNING_DISABLE_GCC("-Wliteral-suffix")
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::literals::chrono_literals::operator""h(unsigned long long x) -> std::chrono::hours
|
||||||
|
{
|
||||||
|
return chrono::hours{x};
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_WARNING_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::literals::chrono_literals::operator""_h(long double x) -> std::chrono::duration<double, std::ratio<3600,1>>
|
||||||
|
{
|
||||||
|
return chrono::duration<double, std::ratio<3600,1>>{x};
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __cplusplus < 201402L
|
||||||
|
QT_WARNING_PUSH
|
||||||
|
QT_WARNING_DISABLE_CLANG("-Wuser-defined-literals")
|
||||||
|
QT_WARNING_DISABLE_GCC("-Wliteral-suffix")
|
||||||
|
|
||||||
|
// available only since C++14
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::literals::chrono_literals::operator""h(long double x) -> std::chrono::duration<double, std::ratio<3600,1>>
|
||||||
|
{
|
||||||
|
return chrono::duration<double, std::ratio<3600,1>>{x};
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_WARNING_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::literals::chrono_literals::operator""_min(unsigned long long x) -> bpstd::chrono::minutes
|
||||||
|
{
|
||||||
|
return chrono::minutes{x};
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __cplusplus < 201402L
|
||||||
|
QT_WARNING_PUSH
|
||||||
|
QT_WARNING_DISABLE_CLANG("-Wuser-defined-literals")
|
||||||
|
QT_WARNING_DISABLE_GCC("-Wliteral-suffix")
|
||||||
|
|
||||||
|
// available only since C++14
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::literals::chrono_literals::operator""min(unsigned long long x) -> bpstd::chrono::minutes
|
||||||
|
{
|
||||||
|
return chrono::minutes{x};
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_WARNING_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::literals::chrono_literals::operator""_min(long double x) -> bpstd::chrono::duration<double, std::ratio<60>>
|
||||||
|
{
|
||||||
|
return chrono::duration<double, std::ratio<60>>{x};
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __cplusplus < 201402L
|
||||||
|
QT_WARNING_PUSH
|
||||||
|
QT_WARNING_DISABLE_CLANG("-Wuser-defined-literals")
|
||||||
|
QT_WARNING_DISABLE_GCC("-Wliteral-suffix")
|
||||||
|
|
||||||
|
// available only since C++14
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::literals::chrono_literals::operator""min(long double x) -> bpstd::chrono::duration<double, std::ratio<60>>
|
||||||
|
{
|
||||||
|
return chrono::duration<double, std::ratio<60>>{x};
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_WARNING_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::literals::chrono_literals::operator""_s(unsigned long long x) -> bpstd::chrono::seconds
|
||||||
|
{
|
||||||
|
return chrono::seconds{x};
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __cplusplus < 201402L
|
||||||
|
QT_WARNING_PUSH
|
||||||
|
QT_WARNING_DISABLE_CLANG("-Wuser-defined-literals")
|
||||||
|
QT_WARNING_DISABLE_GCC("-Wliteral-suffix")
|
||||||
|
|
||||||
|
// available only since C++14
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::literals::chrono_literals::operator""s(unsigned long long x) -> bpstd::chrono::seconds
|
||||||
|
{
|
||||||
|
return chrono::seconds{x};
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_WARNING_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::literals::chrono_literals::operator""_s(long double x) -> bpstd::chrono::duration<double>
|
||||||
|
{
|
||||||
|
return chrono::duration<double>{x};
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __cplusplus < 201402L
|
||||||
|
QT_WARNING_PUSH
|
||||||
|
QT_WARNING_DISABLE_CLANG("-Wuser-defined-literals")
|
||||||
|
QT_WARNING_DISABLE_GCC("-Wliteral-suffix")
|
||||||
|
|
||||||
|
// available only since C++14
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::literals::chrono_literals::operator""s(long double x) -> bpstd::chrono::duration<double>
|
||||||
|
{
|
||||||
|
return chrono::duration<double>{x};
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_WARNING_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::literals::chrono_literals::operator""_ms(unsigned long long x) -> bpstd::chrono::milliseconds
|
||||||
|
{
|
||||||
|
return chrono::milliseconds{x};
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __cplusplus < 201402L
|
||||||
|
QT_WARNING_PUSH
|
||||||
|
QT_WARNING_DISABLE_CLANG("-Wuser-defined-literals")
|
||||||
|
QT_WARNING_DISABLE_GCC("-Wliteral-suffix")
|
||||||
|
|
||||||
|
// available only since C++14
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::literals::chrono_literals::operator""ms(unsigned long long x) -> bpstd::chrono::milliseconds
|
||||||
|
{
|
||||||
|
return chrono::milliseconds{x};
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_WARNING_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::literals::chrono_literals::operator""_ms(long double x) -> bpstd::chrono::duration<double, std::milli>
|
||||||
|
{
|
||||||
|
return chrono::duration<double, std::milli>{x};
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __cplusplus < 201402L
|
||||||
|
QT_WARNING_PUSH
|
||||||
|
QT_WARNING_DISABLE_CLANG("-Wuser-defined-literals")
|
||||||
|
QT_WARNING_DISABLE_GCC("-Wliteral-suffix")
|
||||||
|
|
||||||
|
// available only since C++14
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::literals::chrono_literals::operator""ms(long double x) -> bpstd::chrono::duration<double, std::milli>
|
||||||
|
{
|
||||||
|
return chrono::duration<double, std::milli>{x};
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_WARNING_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::literals::chrono_literals::operator ""_us(unsigned long long x) -> bpstd::chrono::microseconds
|
||||||
|
{
|
||||||
|
return chrono::microseconds{x};
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __cplusplus < 201402L
|
||||||
|
QT_WARNING_PUSH
|
||||||
|
QT_WARNING_DISABLE_CLANG("-Wuser-defined-literals")
|
||||||
|
QT_WARNING_DISABLE_GCC("-Wliteral-suffix")
|
||||||
|
|
||||||
|
// available only since C++14
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::literals::chrono_literals::operator ""us(unsigned long long x) -> bpstd::chrono::microseconds
|
||||||
|
{
|
||||||
|
return chrono::microseconds{x};
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_WARNING_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::literals::chrono_literals::operator""_us(long double x) -> bpstd::chrono::duration<double, std::micro>
|
||||||
|
{
|
||||||
|
return chrono::duration<double, std::micro>{x};
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __cplusplus < 201402L
|
||||||
|
QT_WARNING_PUSH
|
||||||
|
QT_WARNING_DISABLE_CLANG("-Wuser-defined-literals")
|
||||||
|
QT_WARNING_DISABLE_GCC("-Wliteral-suffix")
|
||||||
|
|
||||||
|
// available only since C++14
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::literals::chrono_literals::operator""us(long double x) -> bpstd::chrono::duration<double, std::micro>
|
||||||
|
{
|
||||||
|
return chrono::duration<double, std::micro>{x};
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_WARNING_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::literals::chrono_literals::operator""_ns(unsigned long long x) -> bpstd::chrono::nanoseconds
|
||||||
|
{
|
||||||
|
return chrono::nanoseconds{x};
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __cplusplus < 201402L
|
||||||
|
QT_WARNING_PUSH
|
||||||
|
QT_WARNING_DISABLE_CLANG("-Wuser-defined-literals")
|
||||||
|
QT_WARNING_DISABLE_GCC("-Wliteral-suffix")
|
||||||
|
|
||||||
|
// available only since C++14
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::literals::chrono_literals::operator""ns(unsigned long long x) -> bpstd::chrono::nanoseconds
|
||||||
|
{
|
||||||
|
return chrono::nanoseconds{x};
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_WARNING_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::literals::chrono_literals::operator""_ns(long double x) -> bpstd::chrono::duration<double, std::nano>
|
||||||
|
{
|
||||||
|
return chrono::duration<double, std::nano>{x};
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __cplusplus < 201402L
|
||||||
|
QT_WARNING_PUSH
|
||||||
|
QT_WARNING_DISABLE_CLANG("-Wuser-defined-literals")
|
||||||
|
QT_WARNING_DISABLE_GCC("-Wliteral-suffix")
|
||||||
|
|
||||||
|
// available only since C++14
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::literals::chrono_literals::operator""ns(long double x) -> bpstd::chrono::duration<double, std::nano>
|
||||||
|
{
|
||||||
|
return chrono::duration<double, std::nano>{x};
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_WARNING_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE
|
||||||
|
|
||||||
|
#endif /* BPSTD_CHRONO_HPP */
|
122
src/libs/vmisc/bpstd/complex.hpp
Normal file
122
src/libs/vmisc/bpstd/complex.hpp
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \file complex.hpp
|
||||||
|
///
|
||||||
|
/// \brief This header provides definitions from the C++ header <complex>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2020 Matthew Rodusek All rights reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef BPSTD_COMPLEX_HPP
|
||||||
|
#define BPSTD_COMPLEX_HPP
|
||||||
|
|
||||||
|
#include "detail/config.hpp"
|
||||||
|
|
||||||
|
#include <complex>
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
|
||||||
|
|
||||||
|
namespace bpstd {
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// class : complex
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using complex = std::complex<T>;
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// literals : class : complex
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
inline namespace literals {
|
||||||
|
inline namespace complex_literals {
|
||||||
|
|
||||||
|
constexpr complex<long double> operator""_il(long double i) noexcept;
|
||||||
|
constexpr complex<long double> operator""_il(unsigned long long i) noexcept;
|
||||||
|
|
||||||
|
constexpr complex<double> operator""_i(long double i) noexcept;
|
||||||
|
constexpr complex<double> operator""_i(unsigned long long i) noexcept;
|
||||||
|
|
||||||
|
constexpr complex<float> operator""_if(long double i) noexcept;
|
||||||
|
constexpr complex<float> operator""_if(unsigned long long i) noexcept;
|
||||||
|
|
||||||
|
} // namespace complex_literals
|
||||||
|
} // namespace literals
|
||||||
|
} // namespace bpstd
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
// literals : class : complex
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::complex<long double>
|
||||||
|
bpstd::literals::complex_literals::operator""_il(long double i)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return complex<long double>{0, i};
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::complex<long double>
|
||||||
|
bpstd::literals::complex_literals::operator""_il(unsigned long long i)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return complex<long double>{0, static_cast<long double>(i)};
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::complex<double>
|
||||||
|
bpstd::literals::complex_literals::operator""_i(long double i)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return complex<double>{0, static_cast<double>(i)};
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::complex<double>
|
||||||
|
bpstd::literals::complex_literals::operator""_i(unsigned long long i)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return complex<double>{0, static_cast<double>(i)};
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::complex<float>
|
||||||
|
bpstd::literals::complex_literals::operator""_if(long double i)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return complex<float>{0, static_cast<float>(i)};
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::complex<float>
|
||||||
|
bpstd::literals::complex_literals::operator""_if(unsigned long long i)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return complex<float>{0, static_cast<float>(i)};
|
||||||
|
}
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE
|
||||||
|
|
||||||
|
#endif /* BPSTD_COMPLEX_HPP */
|
258
src/libs/vmisc/bpstd/cstddef.hpp
Normal file
258
src/libs/vmisc/bpstd/cstddef.hpp
Normal file
|
@ -0,0 +1,258 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \file cstddef.hpp
|
||||||
|
///
|
||||||
|
/// \brief This header provides definitions from the C++ header <cstddef>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2020 Matthew Rodusek All rights reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef BPSTD_CSTDDEF_HPP
|
||||||
|
#define BPSTD_CSTDDEF_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include "detail/config.hpp"
|
||||||
|
#include "type_traits.hpp"
|
||||||
|
|
||||||
|
#include <type_traits> // std::is_integral
|
||||||
|
#include <cstddef> // __cpp_lib_byte, and to proxy API
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
|
||||||
|
|
||||||
|
// The below implementation is based on GSL's implementation of 'gsl::byte'
|
||||||
|
|
||||||
|
// VS2017 15.8 added support for the __cpp_lib_byte definition
|
||||||
|
// To do: drop _HAS_STD_BYTE when support for pre 15.8 expires
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
|
||||||
|
// Turn MSVC /analyze rules that generate too much noise.
|
||||||
|
# pragma warning(push)
|
||||||
|
# pragma warning(disable : 26493) // don't use c-style cast
|
||||||
|
|
||||||
|
# if !defined(BPSTD_USE_STD_BYTE)
|
||||||
|
// this tests if we are under MSVC and the standard lib has std::byte and it is
|
||||||
|
// enabled
|
||||||
|
# if defined(_HAS_STD_BYTE) && _HAS_STD_BYTE
|
||||||
|
# define BPSTD_USE_STD_BYTE 1
|
||||||
|
# elif defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603
|
||||||
|
# define BPSTD_USE_STD_BYTE 1
|
||||||
|
# else
|
||||||
|
# define BPSTD_USE_STD_BYTE 0
|
||||||
|
# endif
|
||||||
|
# endif // BPSTD_USE_STD_BYTE
|
||||||
|
#endif // _MSC_VER
|
||||||
|
|
||||||
|
#if !defined(BPSTD_USE_STD_BYTE)
|
||||||
|
|
||||||
|
// this tests if we are under GCC or Clang with enough -std:c++1z power to get us std::byte
|
||||||
|
// also check if libc++ version is sufficient (> 5.0) or libstc++ actually contains std::byte
|
||||||
|
# if defined(__cplusplus) && (__cplusplus >= 201703L) && \
|
||||||
|
(defined(__cpp_lib_byte) && (__cpp_lib_byte >= 201603) || \
|
||||||
|
defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 5000))
|
||||||
|
# define BPSTD_USE_STD_BYTE 1
|
||||||
|
# else
|
||||||
|
# define BPSTD_USE_STD_BYTE 0
|
||||||
|
# endif
|
||||||
|
#endif // BPSTD_USE_STD_BYTE
|
||||||
|
|
||||||
|
namespace bpstd {
|
||||||
|
|
||||||
|
#if BPSTD_USE_STD_BYTE
|
||||||
|
using std::byte;
|
||||||
|
#else
|
||||||
|
enum class BPSTD_MAY_ALIAS byte : unsigned char {};
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// non-member functions : enum lass : byte
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Bitwise operators
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename Integer,
|
||||||
|
typename = enable_if_t<std::is_integral<Integer>::value>>
|
||||||
|
constexpr byte operator<<(byte b, Integer shift) noexcept;
|
||||||
|
template <typename Integer,
|
||||||
|
typename = enable_if_t<std::is_integral<Integer>::value>>
|
||||||
|
constexpr byte operator>>(byte b, Integer shift) noexcept;
|
||||||
|
|
||||||
|
constexpr byte operator|(byte lhs, byte rhs) noexcept;
|
||||||
|
constexpr byte operator&(byte lhs, byte rhs) noexcept;
|
||||||
|
constexpr byte operator^(byte lhs, byte rhs) noexcept;
|
||||||
|
constexpr byte operator~(byte b) noexcept;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Compound Bitwise Operators
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename Integer,
|
||||||
|
typename = enable_if_t<std::is_integral<Integer>::value>>
|
||||||
|
BPSTD_CPP14_CONSTEXPR byte& operator<<=(byte& b, Integer shift) noexcept;
|
||||||
|
template <typename Integer,
|
||||||
|
typename = enable_if_t<std::is_integral<Integer>::value>>
|
||||||
|
BPSTD_CPP14_CONSTEXPR byte& operator>>=(byte& b, Integer shift) noexcept;
|
||||||
|
BPSTD_CPP14_CONSTEXPR byte& operator|=(byte& lhs, byte rhs) noexcept;
|
||||||
|
BPSTD_CPP14_CONSTEXPR byte& operator&=(byte& lhs, byte rhs) noexcept;
|
||||||
|
|
||||||
|
BPSTD_CPP14_CONSTEXPR byte& operator^=(byte& lhs, byte rhs) noexcept;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Utilities
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename Integer,
|
||||||
|
typename = enable_if_t<std::is_integral<Integer>::value>>
|
||||||
|
constexpr Integer to_integer(byte b) noexcept;
|
||||||
|
|
||||||
|
} // namespace bpstd
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
// definitions : non-member functions : enum class : byte
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#if !BPSTD_USE_STD_BYTE
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Bitwise Operators
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename Integer, typename>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::byte bpstd::operator<<(byte b, Integer shift)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return static_cast<byte>(static_cast<unsigned char>(b) << shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Integer, typename>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::byte bpstd::operator>>(byte b, Integer shift)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return static_cast<byte>(static_cast<unsigned char>(b) >> shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::byte bpstd::operator|(byte lhs, byte rhs)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return static_cast<byte>(
|
||||||
|
static_cast<unsigned char>(lhs) | static_cast<unsigned char>(rhs)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::byte bpstd::operator&(byte lhs, byte rhs)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return static_cast<byte>(
|
||||||
|
static_cast<unsigned char>(lhs) & static_cast<unsigned char>(rhs)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::byte bpstd::operator^(byte lhs, byte rhs)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return static_cast<byte>(
|
||||||
|
static_cast<unsigned char>(lhs) ^ static_cast<unsigned char>(rhs)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::byte bpstd::operator~(byte b)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return static_cast<byte>(~static_cast<unsigned char>(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Compound Bitwise Operators
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename Integer, typename>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
|
||||||
|
bpstd::byte& bpstd::operator<<=(byte& b, Integer shift)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return b = static_cast<byte>(static_cast<unsigned char>(b) << shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Integer, typename>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
|
||||||
|
bpstd::byte& bpstd::operator>>=(byte& b, Integer shift)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return b = static_cast<byte>(static_cast<unsigned char>(b) >> shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
|
||||||
|
bpstd::byte& bpstd::operator|=(byte& lhs, byte rhs)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return lhs = static_cast<byte>(
|
||||||
|
static_cast<unsigned char>(lhs) | static_cast<unsigned char>(rhs)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
|
||||||
|
bpstd::byte& bpstd::operator&=(byte& lhs, byte rhs)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return lhs = static_cast<byte>(
|
||||||
|
static_cast<unsigned char>(lhs) & static_cast<unsigned char>(rhs)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
|
||||||
|
bpstd::byte& bpstd::operator^=(byte& lhs, byte rhs)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return lhs = static_cast<byte>(
|
||||||
|
static_cast<unsigned char>(lhs) ^ static_cast<unsigned char>(rhs)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // BPSTD_USE_STD_BYTE
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Utilities
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename Integer, typename>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
Integer bpstd::to_integer(byte b)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return static_cast<Integer>(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE
|
||||||
|
|
||||||
|
#endif /* BPSTD_CSTDDEF_HPP */
|
103
src/libs/vmisc/bpstd/detail/config.hpp
Normal file
103
src/libs/vmisc/bpstd/detail/config.hpp
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \file config.hpp
|
||||||
|
///
|
||||||
|
/// \brief This header provides configuration data for the bpstd library
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2020 Matthew Rodusek All rights reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef BPSTD_DETAIL_CONFIG_HPP
|
||||||
|
#define BPSTD_DETAIL_CONFIG_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#if !defined(__cplusplus)
|
||||||
|
# error This library requires a C++ compiler
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// _MSC_VER check is due to MSVC not defining __cplusplus to be 201103L
|
||||||
|
#if !defined(_MSC_VER) && __cplusplus < 201103L
|
||||||
|
# error This library must be compiled with C++11 support
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__cplusplus) && __cplusplus >= 201402L
|
||||||
|
# define BPSTD_CPP14_CONSTEXPR constexpr
|
||||||
|
# define BPSTD_HAS_TEMPLATE_VARIABLES 1
|
||||||
|
#else
|
||||||
|
# define BPSTD_CPP14_CONSTEXPR
|
||||||
|
# define BPSTD_HAS_TEMPLATE_VARIABLES 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__cplusplus) && __cplusplus >= 201703L
|
||||||
|
# define BPSTD_CPP17_CONSTEXPR constexpr
|
||||||
|
# define BPSTD_CPP17_INLINE inline
|
||||||
|
# define BPSTD_HAS_INLINE_VARIABLES 1
|
||||||
|
#else
|
||||||
|
# define BPSTD_CPP17_CONSTEXPR
|
||||||
|
# define BPSTD_CPP17_INLINE
|
||||||
|
# define BPSTD_HAS_INLINE_VARIABLES 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BPSTD_UNUSED(x) static_cast<void>(x)
|
||||||
|
|
||||||
|
// Use __may_alias__ attribute on gcc and clang
|
||||||
|
#if defined(__clang__) || (defined(__GNUC__) && __GNUC__ > 5)
|
||||||
|
# define BPSTD_MAY_ALIAS __attribute__((__may_alias__))
|
||||||
|
#else // defined(__clang__) || defined __GNUC__
|
||||||
|
# define BPSTD_MAY_ALIAS
|
||||||
|
#endif // defined __clang__ || defined __GNUC__
|
||||||
|
|
||||||
|
#if !defined(BPSTD_INLINE_VISIBILITY)
|
||||||
|
// When using 'clang-cl', don't forceinline -- since it results in code generation
|
||||||
|
// failures in 'variant'
|
||||||
|
# if defined(__clang__) && defined(_MSC_VER)
|
||||||
|
# define BPSTD_INLINE_VISIBILITY __attribute__((visibility("hidden"), no_instrument_function))
|
||||||
|
# elif defined(__clang__) || defined(__GNUC__)
|
||||||
|
# define BPSTD_INLINE_VISIBILITY __attribute__((visibility("hidden"), always_inline, no_instrument_function))
|
||||||
|
# elif defined(_MSC_VER)
|
||||||
|
# define BPSTD_INLINE_VISIBILITY __forceinline
|
||||||
|
# else
|
||||||
|
# define BPSTD_INLINE_VISIBILITY
|
||||||
|
# endif
|
||||||
|
#endif // !defined(BPSTD_INLINE_VISIBILITY)
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# define BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE \
|
||||||
|
__pragma(warning(push)) \
|
||||||
|
__pragma(warning(disable:4714)) \
|
||||||
|
__pragma(warning(disable:4100))
|
||||||
|
#else
|
||||||
|
# define BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# define BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE \
|
||||||
|
__pragma(warning(pop))
|
||||||
|
#else
|
||||||
|
# define BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* BPSTD_DETAIL_CONFIG_HPP */
|
73
src/libs/vmisc/bpstd/detail/enable_overload.hpp
Normal file
73
src/libs/vmisc/bpstd/detail/enable_overload.hpp
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \file enable_overload.hpp
|
||||||
|
///
|
||||||
|
/// \brief This internal header provides the definition of a SFINAE utility
|
||||||
|
/// for conditionally enabling overloads
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2020 Matthew Rodusek All rights reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef BPSTD_DETAIL_ENABLE_OVERLOAD_HPP
|
||||||
|
#define BPSTD_DETAIL_ENABLE_OVERLOAD_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
namespace bpstd {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
/// \brief Similar to enable_if, but doesn't sfinae-away a type; instead
|
||||||
|
/// produces an uninstantiable unique type when true
|
||||||
|
///
|
||||||
|
/// This is used to selectively disable constructors, since sfinae doesn't
|
||||||
|
/// work for copy/move constructors
|
||||||
|
template <bool b, typename T>
|
||||||
|
struct enable_overload_if
|
||||||
|
{
|
||||||
|
using type = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct enable_overload_if<false,T>
|
||||||
|
{
|
||||||
|
class type{ type() = delete; ~type() = delete; };
|
||||||
|
};
|
||||||
|
|
||||||
|
template <bool B, typename T>
|
||||||
|
using enable_overload_if_t = typename enable_overload_if<B,T>::type;
|
||||||
|
|
||||||
|
/// \brief Inverse of enable_overload_if
|
||||||
|
template <bool B, typename T>
|
||||||
|
using disable_overload_if = enable_overload_if<!B,T>;
|
||||||
|
|
||||||
|
/// \brief Convenience alias to retrieve the ::type member of
|
||||||
|
/// disable_overload_if
|
||||||
|
template <bool B, typename T>
|
||||||
|
using disable_overload_if_t = typename disable_overload_if<B,T>::type;
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace bpstd
|
||||||
|
|
||||||
|
#endif /* BPSTD_DETAIL_ENABLE_OVERLOAD_HPP */
|
188
src/libs/vmisc/bpstd/detail/invoke.hpp
Normal file
188
src/libs/vmisc/bpstd/detail/invoke.hpp
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \file invoke.hpp
|
||||||
|
///
|
||||||
|
/// \brief This internal header provides the definition of the INVOKE overload
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2020 Matthew Rodusek All rights reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef BPSTD_DETAIL_INVOKE_HPP
|
||||||
|
#define BPSTD_DETAIL_INVOKE_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include "config.hpp" // BPSTD_INLINE_VISIBILITY
|
||||||
|
#include "move.hpp" // forward
|
||||||
|
#include <type_traits> // std::true_type, std::false_type, etc
|
||||||
|
#include <functional> // std::reference_wrapper
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
|
||||||
|
|
||||||
|
namespace bpstd {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct is_reference_wrapper : std::false_type {};
|
||||||
|
|
||||||
|
template<typename U>
|
||||||
|
struct is_reference_wrapper<std::reference_wrapper<U>> : std::true_type {};
|
||||||
|
|
||||||
|
template <typename Base, typename T, typename Derived, typename... Args>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto INVOKE(T Base::*pmf, Derived&& ref, Args&&... args)
|
||||||
|
noexcept(noexcept((::bpstd::forward<Derived>(ref).*pmf)(::bpstd::forward<Args>(args)...)))
|
||||||
|
-> typename std::enable_if<std::is_function<T>::value &&
|
||||||
|
std::is_base_of<Base, typename std::decay<Derived>::type>::value,
|
||||||
|
decltype((::bpstd::forward<Derived>(ref).*pmf)(::bpstd::forward<Args>(args)...))>::type
|
||||||
|
{
|
||||||
|
return (bpstd::forward<Derived>(ref).*pmf)(bpstd::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Base, typename T, typename RefWrap, typename... Args>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto INVOKE(T Base::*pmf, RefWrap&& ref, Args&&... args)
|
||||||
|
noexcept(noexcept((ref.get().*pmf)(std::forward<Args>(args)...)))
|
||||||
|
-> typename std::enable_if<std::is_function<T>::value &&
|
||||||
|
is_reference_wrapper<typename std::decay<RefWrap>::type>::value,
|
||||||
|
decltype((ref.get().*pmf)(::bpstd::forward<Args>(args)...))>::type
|
||||||
|
{
|
||||||
|
return (ref.get().*pmf)(bpstd::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Base, typename T, typename Pointer, typename... Args>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto INVOKE(T Base::*pmf, Pointer&& ptr, Args&&... args)
|
||||||
|
noexcept(noexcept(((*std::forward<Pointer>(ptr)).*pmf)(std::forward<Args>(args)...)))
|
||||||
|
-> typename std::enable_if<std::is_function<T>::value &&
|
||||||
|
!is_reference_wrapper<typename std::decay<Pointer>::type>::value &&
|
||||||
|
!std::is_base_of<Base, typename std::decay<Pointer>::type>::value,
|
||||||
|
decltype(((*::bpstd::forward<Pointer>(ptr)).*pmf)(::bpstd::forward<Args>(args)...))>::type
|
||||||
|
{
|
||||||
|
return ((*bpstd::forward<Pointer>(ptr)).*pmf)(bpstd::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Base, typename T, typename Derived>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto INVOKE(T Base::*pmd, Derived&& ref)
|
||||||
|
noexcept(noexcept(std::forward<Derived>(ref).*pmd))
|
||||||
|
-> typename std::enable_if<!std::is_function<T>::value &&
|
||||||
|
std::is_base_of<Base, typename std::decay<Derived>::type>::value,
|
||||||
|
decltype(::bpstd::forward<Derived>(ref).*pmd)>::type
|
||||||
|
{
|
||||||
|
return bpstd::forward<Derived>(ref).*pmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Base, typename T, typename RefWrap>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto INVOKE(T Base::*pmd, RefWrap&& ref)
|
||||||
|
noexcept(noexcept(ref.get().*pmd))
|
||||||
|
-> typename std::enable_if<!std::is_function<T>::value &&
|
||||||
|
is_reference_wrapper<typename std::decay<RefWrap>::type>::value,
|
||||||
|
decltype(ref.get().*pmd)>::type
|
||||||
|
{
|
||||||
|
return ref.get().*pmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Base, typename T, typename Pointer>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto INVOKE(T Base::*pmd, Pointer&& ptr)
|
||||||
|
noexcept(noexcept((*std::forward<Pointer>(ptr)).*pmd))
|
||||||
|
-> typename std::enable_if<!std::is_function<T>::value &&
|
||||||
|
!is_reference_wrapper<typename std::decay<Pointer>::type>::value &&
|
||||||
|
!std::is_base_of<Base, typename std::decay<Pointer>::type>::value,
|
||||||
|
decltype((*::bpstd::forward<Pointer>(ptr)).*pmd)>::type
|
||||||
|
{
|
||||||
|
return (*bpstd::forward<Pointer>(ptr)).*pmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename F, typename... Args>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto INVOKE(F&& f, Args&&... args)
|
||||||
|
noexcept(noexcept(std::forward<F>(f)(std::forward<Args>(args)...)))
|
||||||
|
-> typename std::enable_if<!std::is_member_pointer<typename std::decay<F>::type>::value,
|
||||||
|
decltype(::bpstd::forward<F>(f)(::bpstd::forward<Args>(args)...))>::type
|
||||||
|
{
|
||||||
|
return bpstd::forward<F>(f)(bpstd::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
// is_nothrow_invocable
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
template <typename Fn, typename...Args>
|
||||||
|
struct is_nothrow_invocable
|
||||||
|
{
|
||||||
|
template <typename Fn2, typename...Args2>
|
||||||
|
static auto test( Fn2&&, Args2&&... )
|
||||||
|
-> decltype(INVOKE(std::declval<Fn2>(), std::declval<Args2>()...),
|
||||||
|
std::integral_constant<bool,noexcept(INVOKE(std::declval<Fn2>(), std::declval<Args2>()...))>{});
|
||||||
|
|
||||||
|
static auto test(...)
|
||||||
|
-> std::false_type;
|
||||||
|
|
||||||
|
using type = decltype(test(std::declval<Fn>(), std::declval<Args>()...));
|
||||||
|
static constexpr bool value = type::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
// is_invocable
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
template<typename Fn, typename...Args>
|
||||||
|
struct is_invocable
|
||||||
|
{
|
||||||
|
template <typename Fn2, typename...Args2>
|
||||||
|
static auto test( Fn2&&, Args2&&... )
|
||||||
|
-> decltype(INVOKE(std::declval<Fn2>(), std::declval<Args2>()...), std::true_type{});
|
||||||
|
|
||||||
|
static auto test(...)
|
||||||
|
-> std::false_type;
|
||||||
|
|
||||||
|
using type = decltype(test(std::declval<Fn>(), std::declval<Args>()...));
|
||||||
|
static constexpr bool value = type::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Used to SFINAE away non-invocable types
|
||||||
|
template <bool B, typename Fn, typename...Args>
|
||||||
|
struct invoke_result_impl{};
|
||||||
|
|
||||||
|
template <typename Fn, typename...Args>
|
||||||
|
struct invoke_result_impl<true, Fn, Args...>{
|
||||||
|
using type = decltype(INVOKE(std::declval<Fn>(), std::declval<Args>()...));
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Fn, typename...Args>
|
||||||
|
struct invoke_result
|
||||||
|
: invoke_result_impl<is_invocable<Fn,Args...>::value, Fn, Args...>{};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace bpstd
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE
|
||||||
|
|
||||||
|
#endif /* BPSTD_DETAIL_INVOKE_HPP */
|
115
src/libs/vmisc/bpstd/detail/move.hpp
Normal file
115
src/libs/vmisc/bpstd/detail/move.hpp
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \file move.hpp
|
||||||
|
///
|
||||||
|
/// \brief This internal header provides the definition of the move and forward
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2020 Matthew Rodusek All rights reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef BPSTD_DETAIL_MOVE_HPP
|
||||||
|
#define BPSTD_DETAIL_MOVE_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include "config.hpp"
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
|
||||||
|
|
||||||
|
namespace bpstd {
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Utilities
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// \{
|
||||||
|
/// \brief Forwards a reference \p t
|
||||||
|
///
|
||||||
|
/// \tparam T the type to forward
|
||||||
|
/// \param t the reference
|
||||||
|
/// \return the forwarded reference
|
||||||
|
template <typename T>
|
||||||
|
constexpr T&& forward(typename std::remove_reference<T>::type& t) noexcept;
|
||||||
|
template <typename T>
|
||||||
|
constexpr T&& forward(typename std::remove_reference<T>::type&& t) noexcept;
|
||||||
|
/// \}
|
||||||
|
|
||||||
|
/// \brief Casts \p x to an rvalue
|
||||||
|
///
|
||||||
|
/// \param x the parameter to move
|
||||||
|
/// \return rvalue reference to \p x
|
||||||
|
template <typename T>
|
||||||
|
constexpr T&& move(T& x) noexcept;
|
||||||
|
|
||||||
|
/// \brief Casts \p x to an rvalue
|
||||||
|
///
|
||||||
|
/// \param x the parameter to move
|
||||||
|
/// \return rvalue reference to \p x
|
||||||
|
template <typename T>
|
||||||
|
constexpr typename std::remove_reference<T>::type&& move(T&& x) noexcept;
|
||||||
|
|
||||||
|
} // namespace bpstd
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Utilities
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
T&& bpstd::forward(typename std::remove_reference<T>::type& t)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return static_cast<T&&>(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
T&& bpstd::forward(typename std::remove_reference<T>::type&& t)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return static_cast<T&&>(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
T&& bpstd::move(T& x)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return static_cast<T&&>(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
typename std::remove_reference<T>::type&& bpstd::move(T&& x)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return static_cast<T&&>(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE
|
||||||
|
|
||||||
|
#endif /* BPSTD_DETAIL_MOVE_HPP */
|
64
src/libs/vmisc/bpstd/detail/nth_type.hpp
Normal file
64
src/libs/vmisc/bpstd/detail/nth_type.hpp
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* \file nth_type.hpp
|
||||||
|
*
|
||||||
|
* \brief This internal header provides the definition of the INVOKE overload
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2020 Matthew Rodusek All rights reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef BPSTD_DETAIL_NTH_TYPE_HPP
|
||||||
|
#define BPSTD_DETAIL_NTH_TYPE_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include <cstddef> // std::size_t
|
||||||
|
|
||||||
|
namespace bpstd {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
/// \brief Gets the nth type from a variadic pack of arguments
|
||||||
|
///
|
||||||
|
/// \tparam N the argument to retrieve
|
||||||
|
/// \tparam Args the arguments to extract from
|
||||||
|
template <std::size_t N, typename...Args>
|
||||||
|
struct nth_type;
|
||||||
|
|
||||||
|
template <std::size_t N, typename Arg0, typename...Args>
|
||||||
|
struct nth_type<N,Arg0,Args...> : nth_type<N-1,Args...>{};
|
||||||
|
|
||||||
|
template <typename Arg0, typename...Args>
|
||||||
|
struct nth_type<0,Arg0,Args...>
|
||||||
|
{
|
||||||
|
using type = Arg0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <std::size_t N, typename...Args>
|
||||||
|
using nth_type_t = typename nth_type<N,Args...>::type;
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace bpstd
|
||||||
|
|
||||||
|
#endif /* BPSTD_DETAIL_NTH_TYPE_HPP */
|
450
src/libs/vmisc/bpstd/detail/proxy_iterator.hpp
Normal file
450
src/libs/vmisc/bpstd/detail/proxy_iterator.hpp
Normal file
|
@ -0,0 +1,450 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \file proxy_iterator.hpp
|
||||||
|
///
|
||||||
|
/// \brief This internal header provides the definition of an iterator wrapper
|
||||||
|
/// type used for uniqueness
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2020 Matthew Rodusek All rights reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef BPSTD_DETAIL_PROXY_ITERATOR_HPP
|
||||||
|
#define BPSTD_DETAIL_PROXY_ITERATOR_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include "config.hpp"
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
|
||||||
|
|
||||||
|
namespace bpstd {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
// class : proxy_iterator
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \brief A thin wrapper around a different iterator type to add
|
||||||
|
/// uniqueness
|
||||||
|
///
|
||||||
|
/// This makes any regular Iterator type such as a pointer to be unique,
|
||||||
|
/// and incomparable to other pointers.
|
||||||
|
///
|
||||||
|
/// \tparam Iterator the pointer type to wrap
|
||||||
|
/// \tparam U a type to make this iterator unique, and not comparable with
|
||||||
|
/// other proxy_iterators
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename Iterator, typename U = void>
|
||||||
|
class proxy_iterator
|
||||||
|
#if __cplusplus < 201703L
|
||||||
|
: public std::iterator<
|
||||||
|
typename std::iterator_traits<Iterator>::iterator_category,
|
||||||
|
typename std::iterator_traits<Iterator>::value_type,
|
||||||
|
typename std::iterator_traits<Iterator>::difference_type,
|
||||||
|
typename std::iterator_traits<Iterator>::pointer,
|
||||||
|
typename std::iterator_traits<Iterator>::reference
|
||||||
|
>
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#if __cplusplus < 201703L
|
||||||
|
using base_type = std::iterator<
|
||||||
|
typename std::iterator_traits<Iterator>::iterator_category,
|
||||||
|
typename std::iterator_traits<Iterator>::value_type,
|
||||||
|
typename std::iterator_traits<Iterator>::difference_type,
|
||||||
|
typename std::iterator_traits<Iterator>::pointer,
|
||||||
|
typename std::iterator_traits<Iterator>::reference
|
||||||
|
>;
|
||||||
|
#endif
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Public Member Types
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
public:
|
||||||
|
|
||||||
|
#if __cplusplus >= 201703L
|
||||||
|
using iterator_category = typename std::iterator_traits<Iterator>::iterator_category;
|
||||||
|
using value_type = typename std::iterator_traits<Iterator>::value_type;
|
||||||
|
using pointer = typename std::iterator_traits<Iterator>::pointer;
|
||||||
|
using reference = typename std::iterator_traits<Iterator>::reference;
|
||||||
|
using difference_type = typename std::iterator_traits<Iterator>::difference_type;
|
||||||
|
#else
|
||||||
|
using iterator_category = typename base_type::iterator_category;
|
||||||
|
using value_type = typename base_type::value_type;
|
||||||
|
using pointer = typename base_type::pointer;
|
||||||
|
using reference = typename base_type::reference;
|
||||||
|
using difference_type = typename base_type::difference_type;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Constructor
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// \brief Default constructs this proxy_iterator by default-constructing
|
||||||
|
/// the underlying iterator
|
||||||
|
constexpr proxy_iterator() = default;
|
||||||
|
|
||||||
|
/// \brief Constructs a proxy_iterator from a given pointer
|
||||||
|
///
|
||||||
|
/// \param it the iterator to construct this proxy_iterator
|
||||||
|
constexpr explicit proxy_iterator(const Iterator& it) noexcept;
|
||||||
|
|
||||||
|
/// \brief Convert-constructs a proxy_iterator from a proxy iterator with
|
||||||
|
/// the same tag
|
||||||
|
///
|
||||||
|
/// \param it the iterator
|
||||||
|
template <typename UIterator>
|
||||||
|
constexpr proxy_iterator(const proxy_iterator<UIterator,U>& it) noexcept;
|
||||||
|
|
||||||
|
/// \brief Copy-constructs a proxy_iterator
|
||||||
|
///
|
||||||
|
/// \param other the iterator to copy
|
||||||
|
constexpr proxy_iterator(const proxy_iterator& other) noexcept = default;
|
||||||
|
|
||||||
|
/// \brief Move-constructs a proxy_iterator
|
||||||
|
///
|
||||||
|
/// \param other the iterator to move
|
||||||
|
constexpr proxy_iterator(proxy_iterator&& other) noexcept = default;
|
||||||
|
|
||||||
|
/// \brief Copy-assigns a proxy_iterator
|
||||||
|
///
|
||||||
|
/// \param it the iterator to copy
|
||||||
|
template <typename UIterator>
|
||||||
|
proxy_iterator& operator=(const proxy_iterator<UIterator,U>& it) noexcept;
|
||||||
|
|
||||||
|
/// \brief Copy-assigns a proxy_iterator
|
||||||
|
///
|
||||||
|
/// \param other the iterator to copy
|
||||||
|
proxy_iterator& operator=(const proxy_iterator& other) noexcept = default;
|
||||||
|
|
||||||
|
/// \brief Move-assigns a proxy_iterator
|
||||||
|
///
|
||||||
|
/// \param other the iterator to move
|
||||||
|
proxy_iterator& operator=(proxy_iterator&& other) noexcept = default;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Iteration
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
public:
|
||||||
|
|
||||||
|
BPSTD_CPP14_CONSTEXPR proxy_iterator& operator++() noexcept;
|
||||||
|
BPSTD_CPP14_CONSTEXPR proxy_iterator operator++(int) noexcept;
|
||||||
|
BPSTD_CPP14_CONSTEXPR proxy_iterator& operator--() noexcept;
|
||||||
|
BPSTD_CPP14_CONSTEXPR proxy_iterator operator--(int) noexcept;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Random Access
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
public:
|
||||||
|
|
||||||
|
BPSTD_CPP14_CONSTEXPR proxy_iterator& operator+=(difference_type n) noexcept;
|
||||||
|
BPSTD_CPP14_CONSTEXPR proxy_iterator& operator-=(difference_type n) noexcept;
|
||||||
|
|
||||||
|
constexpr difference_type operator-(const proxy_iterator& rhs) const noexcept;
|
||||||
|
constexpr reference operator[](difference_type index) const noexcept;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Observers
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
public:
|
||||||
|
|
||||||
|
constexpr pointer operator->() const noexcept;
|
||||||
|
constexpr reference operator*() const noexcept;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Comparison
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
public:
|
||||||
|
|
||||||
|
constexpr bool operator==(const proxy_iterator& rhs) const noexcept;
|
||||||
|
constexpr bool operator!=(const proxy_iterator& rhs) const noexcept;
|
||||||
|
constexpr bool operator< (const proxy_iterator& rhs) const noexcept;
|
||||||
|
constexpr bool operator<=(const proxy_iterator& rhs) const noexcept;
|
||||||
|
constexpr bool operator> (const proxy_iterator& rhs) const noexcept;
|
||||||
|
constexpr bool operator>=(const proxy_iterator& rhs) const noexcept;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Private Members
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
private:
|
||||||
|
|
||||||
|
Iterator m_iter; ///< The iterator used for iteration
|
||||||
|
|
||||||
|
template <typename, typename> friend class proxy_iterator;
|
||||||
|
};
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
// non-member functions : class : proxy_iterator
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Random Access
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template<typename Iterator, typename U>
|
||||||
|
BPSTD_CPP14_CONSTEXPR proxy_iterator<Iterator,U>
|
||||||
|
operator+(const proxy_iterator<Iterator,U>& lhs,
|
||||||
|
typename proxy_iterator<Iterator,U>::difference_type rhs) noexcept;
|
||||||
|
|
||||||
|
template<typename Iterator, typename U>
|
||||||
|
BPSTD_CPP14_CONSTEXPR proxy_iterator<Iterator,U>
|
||||||
|
operator+(typename proxy_iterator<Iterator,U>::difference_type lhs,
|
||||||
|
const proxy_iterator<Iterator,U>& rhs) noexcept;
|
||||||
|
|
||||||
|
template<typename Iterator, typename U>
|
||||||
|
BPSTD_CPP14_CONSTEXPR proxy_iterator<Iterator,U>
|
||||||
|
operator-(const proxy_iterator<Iterator,U>& lhs,
|
||||||
|
typename proxy_iterator<Iterator,U>::difference_type rhs) noexcept;
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace bpstd
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
// definitions : class : proxy_iterator
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Constructors / Assignment
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template<typename Iterator, typename U>
|
||||||
|
inline constexpr bpstd::detail::proxy_iterator<Iterator,U>::
|
||||||
|
proxy_iterator(const Iterator& it)
|
||||||
|
noexcept
|
||||||
|
: m_iter{it}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Iterator, typename U>
|
||||||
|
template <typename UIterator>
|
||||||
|
inline constexpr bpstd::detail::proxy_iterator<Iterator,U>
|
||||||
|
::proxy_iterator(const proxy_iterator<UIterator,U>& it)
|
||||||
|
noexcept
|
||||||
|
: m_iter{it.m_iter}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Iterator, typename U>
|
||||||
|
template <typename UIterator>
|
||||||
|
inline bpstd::detail::proxy_iterator<Iterator,U>&
|
||||||
|
bpstd::detail::proxy_iterator<Iterator,U>::operator=(const proxy_iterator<UIterator,U>& it)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
m_iter = it.m_iter;
|
||||||
|
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Iteration
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template<typename Iterator, typename U>
|
||||||
|
inline BPSTD_CPP14_CONSTEXPR bpstd::detail::proxy_iterator<Iterator,U>&
|
||||||
|
bpstd::detail::proxy_iterator<Iterator,U>::operator++()
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
++m_iter;
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Iterator, typename U>
|
||||||
|
inline BPSTD_CPP14_CONSTEXPR bpstd::detail::proxy_iterator<Iterator,U>
|
||||||
|
bpstd::detail::proxy_iterator<Iterator,U>::operator++(int)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return proxy_iterator{m_iter++};
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template<typename Iterator, typename U>
|
||||||
|
inline BPSTD_CPP14_CONSTEXPR bpstd::detail::proxy_iterator<Iterator,U>&
|
||||||
|
bpstd::detail::proxy_iterator<Iterator,U>::operator--()
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
--m_iter;
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Iterator, typename U>
|
||||||
|
inline BPSTD_CPP14_CONSTEXPR bpstd::detail::proxy_iterator<Iterator,U>
|
||||||
|
bpstd::detail::proxy_iterator<Iterator,U>::operator--(int)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return proxy_iterator{m_iter--};
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Random Access
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template<typename Iterator, typename U>
|
||||||
|
inline BPSTD_CPP14_CONSTEXPR bpstd::detail::proxy_iterator<Iterator,U>&
|
||||||
|
bpstd::detail::proxy_iterator<Iterator,U>::operator+=(difference_type n)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
m_iter += n;
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Iterator, typename U>
|
||||||
|
inline BPSTD_CPP14_CONSTEXPR bpstd::detail::proxy_iterator<Iterator,U>&
|
||||||
|
bpstd::detail::proxy_iterator<Iterator,U>::operator-=(difference_type n)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
m_iter -= n;
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Iterator, typename U>
|
||||||
|
inline constexpr typename bpstd::detail::proxy_iterator<Iterator,U>::difference_type
|
||||||
|
bpstd::detail::proxy_iterator<Iterator,U>::operator-(const proxy_iterator<Iterator,U>& rhs)
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
return m_iter - rhs.m_iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Iterator, typename U>
|
||||||
|
inline constexpr typename bpstd::detail::proxy_iterator<Iterator,U>::reference
|
||||||
|
bpstd::detail::proxy_iterator<Iterator,U>::operator[](difference_type index)
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
return m_iter[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Observers
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template<typename Iterator, typename U>
|
||||||
|
inline constexpr typename bpstd::detail::proxy_iterator<Iterator,U>::pointer
|
||||||
|
bpstd::detail::proxy_iterator<Iterator,U>::operator->()
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
return m_iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Iterator, typename U>
|
||||||
|
inline constexpr typename bpstd::detail::proxy_iterator<Iterator,U>::reference
|
||||||
|
bpstd::detail::proxy_iterator<Iterator,U>::operator*()
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
return *m_iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Comparisons
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template<typename Iterator, typename U>
|
||||||
|
inline constexpr bool
|
||||||
|
bpstd::detail::proxy_iterator<Iterator,U>::operator==(const proxy_iterator& rhs)
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
return m_iter == rhs.m_iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Iterator, typename U>
|
||||||
|
inline constexpr bool
|
||||||
|
bpstd::detail::proxy_iterator<Iterator,U>::operator!=(const proxy_iterator& rhs)
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
return m_iter != rhs.m_iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Iterator, typename U>
|
||||||
|
inline constexpr bool
|
||||||
|
bpstd::detail::proxy_iterator<Iterator,U>::operator<(const proxy_iterator& rhs)
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
return m_iter < rhs.m_iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Iterator, typename U>
|
||||||
|
inline constexpr bool
|
||||||
|
bpstd::detail::proxy_iterator<Iterator,U>::operator<=(const proxy_iterator& rhs)
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
return m_iter <= rhs.m_iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Iterator, typename U>
|
||||||
|
inline constexpr bool
|
||||||
|
bpstd::detail::proxy_iterator<Iterator,U>::operator>(const proxy_iterator& rhs)
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
return m_iter > rhs.m_iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Iterator, typename U>
|
||||||
|
inline constexpr bool
|
||||||
|
bpstd::detail::proxy_iterator<Iterator,U>::operator>=(const proxy_iterator& rhs)
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
return m_iter >= rhs.m_iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
// definitions : non-member functions : class : proxy_iterator
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Random Access (free functions)
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template<typename Iterator, typename U>
|
||||||
|
inline BPSTD_CPP14_CONSTEXPR bpstd::detail::proxy_iterator<Iterator,U>
|
||||||
|
bpstd::detail::operator+(const proxy_iterator<Iterator,U>& lhs,
|
||||||
|
typename proxy_iterator<Iterator,U>::difference_type rhs)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return proxy_iterator<Iterator,U>{lhs} += rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Iterator, typename U>
|
||||||
|
inline BPSTD_CPP14_CONSTEXPR bpstd::detail::proxy_iterator<Iterator,U>
|
||||||
|
bpstd::detail::operator+(typename proxy_iterator<Iterator,U>::difference_type lhs,
|
||||||
|
const proxy_iterator<Iterator,U>& rhs)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return proxy_iterator<Iterator,U>{rhs} += lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Iterator, typename U>
|
||||||
|
inline BPSTD_CPP14_CONSTEXPR bpstd::detail::proxy_iterator<Iterator,U>
|
||||||
|
bpstd::detail::operator-(const proxy_iterator<Iterator,U>& lhs,
|
||||||
|
typename proxy_iterator<Iterator,U>::difference_type rhs)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return proxy_iterator<Iterator,U>{lhs} -= rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE
|
||||||
|
|
||||||
|
#endif /* BPSTD_DETAIL_PROXY_ITERATOR_HPP */
|
240
src/libs/vmisc/bpstd/detail/variant_base.hpp
Normal file
240
src/libs/vmisc/bpstd/detail/variant_base.hpp
Normal file
|
@ -0,0 +1,240 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* \file variant_base.hpp
|
||||||
|
*
|
||||||
|
* \brief This internal header provides the definition of a utility for
|
||||||
|
* variant, variant_base
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2020 Matthew Rodusek All rights reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef BPSTD_DETAIL_VARIANT_BASE_HPP
|
||||||
|
#define BPSTD_DETAIL_VARIANT_BASE_HPP
|
||||||
|
|
||||||
|
#include "config.hpp" // BPSTD_CPP14_CONSTEXPR
|
||||||
|
#include "variant_union.hpp" // detail::variant_union
|
||||||
|
|
||||||
|
#include <cstddef> // std::size_t
|
||||||
|
#include <utility> // std::forward
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
|
||||||
|
|
||||||
|
namespace bpstd {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
// class : variant_base
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \brief The base class used by variant
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <bool IsTrivial, typename...Types>
|
||||||
|
class variant_base;
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
// class : variant_base<true, Types...>
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
template <typename...Types>
|
||||||
|
class variant_base<true,Types...>
|
||||||
|
{
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Constructors
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
public:
|
||||||
|
|
||||||
|
constexpr variant_base();
|
||||||
|
|
||||||
|
template <std::size_t N, typename...Args>
|
||||||
|
constexpr variant_base(variant_index_tag<N>, Args&&...args);
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Protected Members
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
protected:
|
||||||
|
|
||||||
|
variant_union<true,Types...> m_union;
|
||||||
|
std::size_t m_index;
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Protected Member Functions
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void destroy_active_object();
|
||||||
|
};
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
// class : variant_base<false, Types...>
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
template <typename...Types>
|
||||||
|
class variant_base<false,Types...>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
constexpr variant_base();
|
||||||
|
|
||||||
|
template <std::size_t N, typename...Args>
|
||||||
|
constexpr variant_base(variant_index_tag<N>, Args&&...args);
|
||||||
|
|
||||||
|
~variant_base();
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Protected Members
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
protected:
|
||||||
|
|
||||||
|
variant_union<false,Types...> m_union;
|
||||||
|
std::size_t m_index;
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Protected Member Functions
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void destroy_active_object();
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Private Static Member Functions
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
private:
|
||||||
|
|
||||||
|
struct destroy_visitor
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
void operator()(T& v) {
|
||||||
|
v.~T();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace bpstd
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
// class : variant_base<true, Types...>
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Constructors
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename...Types>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::detail::variant_base<true,Types...>::variant_base()
|
||||||
|
: m_union{},
|
||||||
|
m_index{static_cast<std::size_t>(-1)}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename...Types>
|
||||||
|
template <std::size_t N, typename...Args>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::detail::variant_base<true,Types...>::variant_base(variant_index_tag<N>,
|
||||||
|
Args&&...args)
|
||||||
|
: m_union{variant_index_tag<N>{}, std::forward<Args>(args)...},
|
||||||
|
m_index{N}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Protected Members
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename...Types>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
void bpstd::detail::variant_base<true,Types...>::destroy_active_object()
|
||||||
|
{
|
||||||
|
m_index = static_cast<std::size_t>(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
// class : variant_base<false, Types...>
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Constructors / Destructor
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename...Types>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::detail::variant_base<false,Types...>::variant_base()
|
||||||
|
: m_union{},
|
||||||
|
m_index{static_cast<std::size_t>(-1)}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma warning(push)
|
||||||
|
# pragma warning(disable:4702)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <typename...Types>
|
||||||
|
template <std::size_t N, typename...Args>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::detail::variant_base<false,Types...>::variant_base(variant_index_tag<N>,
|
||||||
|
Args&&...args)
|
||||||
|
: m_union{variant_index_tag<N>{}, std::forward<Args>(args)...},
|
||||||
|
m_index{N}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename...Types>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
bpstd::detail::variant_base<false,Types...>::~variant_base()
|
||||||
|
{
|
||||||
|
destroy_active_object();
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Protected Members
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename...Types>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
void bpstd::detail::variant_base<false,Types...>::destroy_active_object()
|
||||||
|
{
|
||||||
|
if (m_index == static_cast<std::size_t>(-1)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
visit_union(m_index, destroy_visitor{}, m_union);
|
||||||
|
m_index = static_cast<std::size_t>(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE
|
||||||
|
|
||||||
|
#endif /* BPSTD_DETAIL_VARIANT_BASE_HPP */
|
50
src/libs/vmisc/bpstd/detail/variant_fwds.hpp
Normal file
50
src/libs/vmisc/bpstd/detail/variant_fwds.hpp
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* \file variant_fwds.hpp
|
||||||
|
*
|
||||||
|
* \brief This internal header provides forward declarations of various
|
||||||
|
* variant types used internally
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2020 Matthew Rodusek All rights reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef BPSTD_DETAIL_VARIANT_FWDS_HPP
|
||||||
|
#define BPSTD_DETAIL_VARIANT_FWDS_HPP
|
||||||
|
|
||||||
|
namespace bpstd {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template <bool IsTrivial, typename...Types>
|
||||||
|
union variant_union;
|
||||||
|
|
||||||
|
template <bool IsTrivial, typename...Types>
|
||||||
|
class variant_base;
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template <typename...Types>
|
||||||
|
class variant;
|
||||||
|
|
||||||
|
} // namespace bpstd
|
||||||
|
|
||||||
|
#endif /* BPSTD_DETAIL_VARIANT_FWDS_HPP */
|
112
src/libs/vmisc/bpstd/detail/variant_traits.hpp
Normal file
112
src/libs/vmisc/bpstd/detail/variant_traits.hpp
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* \file variant_traits.hpp
|
||||||
|
*
|
||||||
|
* \brief This internal header provides forward declarations of various
|
||||||
|
* variant traits
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2020 Matthew Rodusek All rights reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef BPSTD_DETAIL_VARIANT_TRAITS_HPP
|
||||||
|
#define BPSTD_DETAIL_VARIANT_TRAITS_HPP
|
||||||
|
|
||||||
|
#include "config.hpp"
|
||||||
|
#include "variant_fwds.hpp"
|
||||||
|
#include "invoke.hpp" // invoke_result
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
|
||||||
|
|
||||||
|
namespace bpstd {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template <typename Variant>
|
||||||
|
struct variant_first_type;
|
||||||
|
|
||||||
|
template <bool IsTrivial, typename Type0, typename...Types>
|
||||||
|
struct variant_first_type<variant_union<IsTrivial, Type0, Types...>>
|
||||||
|
{
|
||||||
|
using type = Type0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <bool IsTrivial, typename Type0, typename...Types>
|
||||||
|
struct variant_first_type<variant_base<IsTrivial, Type0, Types...>>
|
||||||
|
{
|
||||||
|
using type = Type0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Type0, typename...Types>
|
||||||
|
struct variant_first_type<variant<Type0, Types...>>
|
||||||
|
{
|
||||||
|
using type = Type0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Variant>
|
||||||
|
struct variant_first_type<Variant&>
|
||||||
|
{
|
||||||
|
using type = typename variant_first_type<Variant>::type&;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Variant>
|
||||||
|
struct variant_first_type<Variant&&>
|
||||||
|
{
|
||||||
|
using type = typename variant_first_type<Variant>::type&&;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Variant>
|
||||||
|
struct variant_first_type<const Variant>
|
||||||
|
{
|
||||||
|
using type = const typename variant_first_type<Variant>::type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Variant>
|
||||||
|
struct variant_first_type<const Variant&>
|
||||||
|
{
|
||||||
|
using type = const typename variant_first_type<Variant>::type&;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Variant>
|
||||||
|
struct variant_first_type<const Variant&&>
|
||||||
|
{
|
||||||
|
using type = const typename variant_first_type<Variant>::type&&;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Variant>
|
||||||
|
using variant_first_type_t = typename variant_first_type<Variant>::type;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename Visitor, typename...Variants>
|
||||||
|
struct variant_visitor_invoke_result
|
||||||
|
: invoke_result<Visitor,variant_first_type_t<Variants>...>{};
|
||||||
|
|
||||||
|
template <typename Visitor, typename...Variants>
|
||||||
|
using variant_visitor_invoke_result_t
|
||||||
|
= typename variant_visitor_invoke_result<Visitor, Variants...>::type;
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace bpstd
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE
|
||||||
|
|
||||||
|
#endif /* BPSTD_DETAIL_VARIANT_TRAITS_HPP */
|
580
src/libs/vmisc/bpstd/detail/variant_union.hpp
Normal file
580
src/libs/vmisc/bpstd/detail/variant_union.hpp
Normal file
|
@ -0,0 +1,580 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* \file variant_union.hpp
|
||||||
|
*
|
||||||
|
* \brief This internal header provides the definition of a utility for
|
||||||
|
* variant, variant_union
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2020 Matthew Rodusek All rights reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef BPSTD_DETAIL_VARIANT_UNION_HPP
|
||||||
|
#define BPSTD_DETAIL_VARIANT_UNION_HPP
|
||||||
|
|
||||||
|
#include "config.hpp" // BPSTD_CPP14_CONSTEXPR
|
||||||
|
#include "nth_type.hpp" // detail::nth_type
|
||||||
|
#include "move.hpp" // forward
|
||||||
|
#include "variant_traits.hpp"
|
||||||
|
|
||||||
|
#include <cstddef> // std::size_t
|
||||||
|
#include <type_traits> // std::decay
|
||||||
|
#include <initializer_list>
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
|
||||||
|
|
||||||
|
namespace bpstd {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template <typename From, typename To>
|
||||||
|
struct match_cv {
|
||||||
|
using type = To;
|
||||||
|
};
|
||||||
|
template <typename From, typename To>
|
||||||
|
struct match_cv<const From, To> {
|
||||||
|
using type = const To;
|
||||||
|
};
|
||||||
|
template <typename From, typename To>
|
||||||
|
struct match_cv<volatile From, To> {
|
||||||
|
using type = volatile To;
|
||||||
|
};
|
||||||
|
template <typename From, typename To>
|
||||||
|
struct match_cv<const volatile From, To> {
|
||||||
|
using type = const volatile To;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename From, typename To>
|
||||||
|
struct match_reference {
|
||||||
|
using type = To&&;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename From, typename To>
|
||||||
|
struct match_reference<From&&, To> {
|
||||||
|
using type = To&&;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename From, typename To>
|
||||||
|
struct match_reference<From&,To> {
|
||||||
|
using type = To&;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename From, typename To>
|
||||||
|
using match_cvref = match_reference<From,
|
||||||
|
typename match_cv<
|
||||||
|
typename std::remove_reference<From>::type,To
|
||||||
|
>::type
|
||||||
|
>;
|
||||||
|
|
||||||
|
template <typename From, typename To>
|
||||||
|
using match_cvref_t = typename match_cvref<From,To>::type;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \brief A tag type used to represent an empty variant
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
struct variant_empty{};
|
||||||
|
|
||||||
|
template <std::size_t N>
|
||||||
|
struct variant_index_tag{};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Implementation of the variant_union class
|
||||||
|
///
|
||||||
|
/// \tparam IsTrivial true if all the types in the variant are trivial
|
||||||
|
/// \tparam Types the types in the variant
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <bool IsTrivial, typename...Types>
|
||||||
|
union variant_union;
|
||||||
|
|
||||||
|
/// \brief A type-trait for retrieving the number of elements in a variant
|
||||||
|
/// union
|
||||||
|
template <typename T>
|
||||||
|
struct variant_union_size
|
||||||
|
: variant_union_size<typename std::decay<T>::type>{};
|
||||||
|
|
||||||
|
template <bool B, typename...Types>
|
||||||
|
struct variant_union_size<variant_union<B,Types...>>
|
||||||
|
: std::integral_constant<std::size_t,sizeof...(Types)>{};
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
// union : variant_union<true,Type0,Types...>
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
// Partial specialization: All types are trivial; is trivially destructible
|
||||||
|
template <typename Type0, typename...Types>
|
||||||
|
union variant_union<true,Type0,Types...>
|
||||||
|
{
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Public Members Types
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
|
using current_type = Type0;
|
||||||
|
using next_type = variant_union<true,Types...>;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Public Members
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
|
variant_empty empty;
|
||||||
|
current_type current;
|
||||||
|
next_type next;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Constructors
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
|
constexpr variant_union();
|
||||||
|
|
||||||
|
template <typename...Args>
|
||||||
|
constexpr variant_union(variant_index_tag<0>, Args&&...args);
|
||||||
|
|
||||||
|
template <std::size_t N, typename...Args>
|
||||||
|
constexpr variant_union(variant_index_tag<N>, Args&&...args);
|
||||||
|
};
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
// union : variant_union<false,Type0,Types...>
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
// Partial specialization: At least one type is not trivial
|
||||||
|
// This specialization needs to exist to explicitly define ~variant_union,
|
||||||
|
// but is otherwise the *only* difference
|
||||||
|
template <typename Type0, typename...Types>
|
||||||
|
union variant_union<false,Type0,Types...>
|
||||||
|
{
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Public Members Types
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
|
using current_type = Type0;
|
||||||
|
using next_type = variant_union<false,Types...>;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Public Members
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
|
variant_empty empty;
|
||||||
|
current_type current;
|
||||||
|
next_type next;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Constructors / Destructor
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
|
constexpr variant_union();
|
||||||
|
|
||||||
|
template <typename...Args>
|
||||||
|
constexpr variant_union(variant_index_tag<0>, Args&&...args);
|
||||||
|
|
||||||
|
template <std::size_t N, typename...Args>
|
||||||
|
constexpr variant_union(variant_index_tag<N>, Args&&...args);
|
||||||
|
|
||||||
|
~variant_union(){}
|
||||||
|
};
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
// union : variant_union<B>
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
template <bool B>
|
||||||
|
union variant_union<B>
|
||||||
|
{
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Public Members
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
|
variant_empty empty;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Constructors
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
|
constexpr variant_union();
|
||||||
|
|
||||||
|
template <typename...Args>
|
||||||
|
constexpr variant_union(variant_index_tag<0>);
|
||||||
|
};
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
// non-member functions : class : variant_union
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Utilities
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// \brief Visits the element in the variant_union \p v at index \p n
|
||||||
|
///
|
||||||
|
/// \param n the index
|
||||||
|
/// \param fn the function to invoke on the underlying value
|
||||||
|
/// \param v the variant_union
|
||||||
|
template <typename Fn, typename VariantUnion>
|
||||||
|
BPSTD_CPP14_CONSTEXPR bpstd::detail::variant_visitor_invoke_result_t<Fn, VariantUnion>
|
||||||
|
visit_union(std::size_t n, Fn&& fn, VariantUnion&& v);
|
||||||
|
|
||||||
|
/// \brief Visits the elements in the variant_union \p v1 and \p v2 at
|
||||||
|
/// index \p n
|
||||||
|
///
|
||||||
|
/// \note it is assumed that \p n is the active member of both \p v1 and
|
||||||
|
/// \p v2
|
||||||
|
///
|
||||||
|
/// \param n the index
|
||||||
|
/// \param fn the function to invoke on the underlying value
|
||||||
|
/// \param v1 the first variant_union
|
||||||
|
/// \param v2 the second variant_union
|
||||||
|
template <typename Fn, typename VariantUnion, typename UVariantUnion>
|
||||||
|
BPSTD_CPP14_CONSTEXPR bpstd::detail::variant_visitor_invoke_result_t<Fn,VariantUnion,UVariantUnion>
|
||||||
|
visit_union(std::size_t n, Fn&& fn, VariantUnion&& v1, UVariantUnion&& v2);
|
||||||
|
|
||||||
|
/// \{
|
||||||
|
/// \brief Gets the element at index \p N out of the variant_union
|
||||||
|
///
|
||||||
|
/// \tparam N the nth object to retrieve
|
||||||
|
/// \param u the union
|
||||||
|
/// \return the object at N
|
||||||
|
template <std::size_t N, bool IsTrivial, typename...Types>
|
||||||
|
constexpr bpstd::detail::nth_type_t<N,Types...>&
|
||||||
|
union_get(variant_union<IsTrivial,Types...>& u);
|
||||||
|
|
||||||
|
template <std::size_t N, bool IsTrivial, typename...Types>
|
||||||
|
constexpr const bpstd::detail::nth_type_t<N,Types...>&
|
||||||
|
union_get(const variant_union<IsTrivial,Types...>& u);
|
||||||
|
|
||||||
|
template <std::size_t N, bool IsTrivial, typename...Types>
|
||||||
|
constexpr bpstd::detail::nth_type_t<N,Types...>&&
|
||||||
|
union_get(variant_union<IsTrivial,Types...>&& u);
|
||||||
|
|
||||||
|
template <std::size_t N, bool IsTrivial, typename...Types>
|
||||||
|
constexpr const bpstd::detail::nth_type_t<N,Types...>&&
|
||||||
|
union_get(const variant_union<IsTrivial,Types...>&& u);
|
||||||
|
/// \}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace bpstd
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
// union : variant_union<true, Type0, Types...>
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Constructors
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename Type0, typename...Types>
|
||||||
|
inline constexpr bpstd::detail::variant_union<true, Type0, Types...>
|
||||||
|
::variant_union()
|
||||||
|
: empty{}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Type0, typename...Types>
|
||||||
|
template <typename...Args>
|
||||||
|
inline constexpr bpstd::detail::variant_union<true, Type0, Types...>
|
||||||
|
::variant_union(variant_index_tag<0>, Args&&...args)
|
||||||
|
: current(bpstd::forward<Args>(args)...)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Type0, typename...Types>
|
||||||
|
template <std::size_t N, typename...Args>
|
||||||
|
inline constexpr bpstd::detail::variant_union<true, Type0, Types...>
|
||||||
|
::variant_union(variant_index_tag<N>, Args&&...args)
|
||||||
|
: next{variant_index_tag<N-1>{}, bpstd::forward<Args>(args)...}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
// union : variant_union<false, Type0, Types...>
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Constructors
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename Type0, typename...Types>
|
||||||
|
inline constexpr bpstd::detail::variant_union<false, Type0, Types...>
|
||||||
|
::variant_union()
|
||||||
|
: empty{}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Type0, typename...Types>
|
||||||
|
template <typename...Args>
|
||||||
|
inline constexpr bpstd::detail::variant_union<false, Type0, Types...>
|
||||||
|
::variant_union(variant_index_tag<0>, Args&&...args)
|
||||||
|
: current(bpstd::forward<Args>(args)...)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Type0, typename...Types>
|
||||||
|
template <std::size_t N, typename...Args>
|
||||||
|
inline constexpr bpstd::detail::variant_union<false, Type0, Types...>
|
||||||
|
::variant_union(variant_index_tag<N>, Args&&...args)
|
||||||
|
: next{variant_index_tag<N-1>{}, bpstd::forward<Args>(args)...}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
// union : variant_union<B>
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Constructors
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <bool B>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::detail::variant_union<B>::variant_union()
|
||||||
|
: empty{}
|
||||||
|
{
|
||||||
|
// base-case; should never be executed
|
||||||
|
}
|
||||||
|
|
||||||
|
template <bool B>
|
||||||
|
template <typename...Args>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::detail::variant_union<B>::variant_union(variant_index_tag<0>)
|
||||||
|
: empty{}
|
||||||
|
{
|
||||||
|
// base-case; should never be executed
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
// non-member functions : class : variant_union
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Utilities
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace bpstd { namespace detail {
|
||||||
|
|
||||||
|
// Single-case
|
||||||
|
|
||||||
|
template <typename Fn, typename VariantUnion>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
|
||||||
|
bpstd::detail::variant_visitor_invoke_result_t<Fn,VariantUnion>
|
||||||
|
do_visit_union(variant_index_tag<1>,
|
||||||
|
std::size_t n,
|
||||||
|
Fn&& fn,
|
||||||
|
VariantUnion&& v)
|
||||||
|
{
|
||||||
|
BPSTD_UNUSED(n);
|
||||||
|
|
||||||
|
return bpstd::forward<Fn>(fn)(
|
||||||
|
union_get<0>(bpstd::forward<VariantUnion>(v))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t N, typename Fn, typename VariantUnion>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
|
||||||
|
bpstd::detail::variant_visitor_invoke_result_t<Fn,VariantUnion>
|
||||||
|
do_visit_union(variant_index_tag<N>,
|
||||||
|
std::size_t n,
|
||||||
|
Fn&& fn,
|
||||||
|
VariantUnion&& v)
|
||||||
|
{
|
||||||
|
using size_type = variant_union_size<VariantUnion>;
|
||||||
|
|
||||||
|
if (n == 0) {
|
||||||
|
return bpstd::forward<Fn>(fn)(
|
||||||
|
union_get<0>(bpstd::forward<VariantUnion>(v))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return do_visit_union(
|
||||||
|
variant_index_tag<(size_type::value - 1)>{},
|
||||||
|
n-1,
|
||||||
|
bpstd::forward<Fn>(fn),
|
||||||
|
static_cast<match_cvref_t<VariantUnion,decltype(v.next)>>(v.next)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Double-case
|
||||||
|
|
||||||
|
template <typename Fn, typename VariantUnion, typename UVariantUnion>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
|
||||||
|
bpstd::detail::variant_visitor_invoke_result_t<Fn,VariantUnion,UVariantUnion>
|
||||||
|
do_visit_union(variant_index_tag<1>,
|
||||||
|
std::size_t n,
|
||||||
|
Fn&& fn,
|
||||||
|
VariantUnion&& v0,
|
||||||
|
UVariantUnion&& v1)
|
||||||
|
{
|
||||||
|
BPSTD_UNUSED(n);
|
||||||
|
|
||||||
|
return bpstd::forward<Fn>(fn)(
|
||||||
|
union_get<0>(bpstd::forward<VariantUnion>(v0)),
|
||||||
|
union_get<0>(bpstd::forward<UVariantUnion>(v1))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t N, typename Fn, typename VariantUnion, typename UVariantUnion>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
|
||||||
|
bpstd::detail::variant_visitor_invoke_result_t<Fn,VariantUnion,UVariantUnion>
|
||||||
|
do_visit_union(variant_index_tag<N>,
|
||||||
|
std::size_t n,
|
||||||
|
Fn&& fn,
|
||||||
|
VariantUnion&& v0,
|
||||||
|
UVariantUnion&& v1)
|
||||||
|
{
|
||||||
|
using size_type = variant_union_size<VariantUnion>;
|
||||||
|
|
||||||
|
if (n == 0) {
|
||||||
|
return bpstd::forward<Fn>(fn)(
|
||||||
|
union_get<0>(bpstd::forward<VariantUnion>(v0)),
|
||||||
|
union_get<0>(bpstd::forward<UVariantUnion>(v1))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return do_visit_union(
|
||||||
|
variant_index_tag<(size_type::value - 1)>{},
|
||||||
|
n-1,
|
||||||
|
bpstd::forward<Fn>(fn),
|
||||||
|
static_cast<match_cvref_t<VariantUnion,decltype(v0.next)>>(v0.next),
|
||||||
|
static_cast<match_cvref_t<UVariantUnion,decltype(v1.next)>>(v1.next)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}} // namespace bpstd::detail
|
||||||
|
|
||||||
|
template <typename Fn, typename VariantUnion>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
|
||||||
|
bpstd::detail::variant_visitor_invoke_result_t<Fn,VariantUnion>
|
||||||
|
bpstd::detail::visit_union(std::size_t n, Fn&& fn, VariantUnion&& v)
|
||||||
|
{
|
||||||
|
using size_type = variant_union_size<VariantUnion>;
|
||||||
|
|
||||||
|
return detail::do_visit_union(
|
||||||
|
variant_index_tag<size_type::value>{},
|
||||||
|
n,
|
||||||
|
bpstd::forward<Fn>(fn),
|
||||||
|
bpstd::forward<VariantUnion>(v)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Fn, typename VariantUnion, typename UVariantUnion>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
|
||||||
|
bpstd::detail::variant_visitor_invoke_result_t<Fn, VariantUnion, UVariantUnion>
|
||||||
|
bpstd::detail::visit_union(std::size_t n,
|
||||||
|
Fn&& fn,
|
||||||
|
VariantUnion&& v1,
|
||||||
|
UVariantUnion&& v2)
|
||||||
|
{
|
||||||
|
using size_type = variant_union_size<VariantUnion>;
|
||||||
|
|
||||||
|
return detail::do_visit_union(
|
||||||
|
variant_index_tag<size_type::value>{},
|
||||||
|
n,
|
||||||
|
bpstd::forward<Fn>(fn),
|
||||||
|
bpstd::forward<VariantUnion>(v1),
|
||||||
|
bpstd::forward<UVariantUnion>(v2)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace bpstd { namespace detail {
|
||||||
|
|
||||||
|
// private implementation: recurse on index
|
||||||
|
|
||||||
|
template <std::size_t N, bool IsTrivial, typename...Types>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
nth_type_t<N,Types...>&
|
||||||
|
do_union_get(variant_index_tag<N>, variant_union<IsTrivial,Types...>& u)
|
||||||
|
{
|
||||||
|
return do_union_get(variant_index_tag<N-1>{}, u.next);
|
||||||
|
}
|
||||||
|
template <bool IsTrivial, typename...Types>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
nth_type_t<0,Types...>&
|
||||||
|
do_union_get(variant_index_tag<0>, variant_union<IsTrivial,Types...>& u)
|
||||||
|
{
|
||||||
|
return u.current;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t N, bool IsTrivial, typename...Types>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
const nth_type_t<N,Types...>&
|
||||||
|
do_union_get(variant_index_tag<N>, const variant_union<IsTrivial,Types...>& u)
|
||||||
|
{
|
||||||
|
return do_union_get(variant_index_tag<N-1>{}, u.next);
|
||||||
|
}
|
||||||
|
template <bool IsTrivial, typename...Types>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
const nth_type_t<0,Types...>&
|
||||||
|
do_union_get(variant_index_tag<0>, const variant_union<IsTrivial,Types...>& u)
|
||||||
|
{
|
||||||
|
return u.current;
|
||||||
|
}
|
||||||
|
|
||||||
|
}} // namespace bpstd::detail
|
||||||
|
|
||||||
|
template <std::size_t N, bool IsTrivial, typename...Types>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::detail::nth_type_t<N,Types...>&
|
||||||
|
bpstd::detail::union_get(variant_union<IsTrivial,Types...>& u)
|
||||||
|
{
|
||||||
|
static_assert(N < sizeof...(Types), "N index out of bounds");
|
||||||
|
|
||||||
|
return do_union_get(variant_index_tag<N>{}, u);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t N, bool IsTrivial, typename...Types>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
const bpstd::detail::nth_type_t<N,Types...>&
|
||||||
|
bpstd::detail::union_get(const variant_union<IsTrivial,Types...>& u)
|
||||||
|
{
|
||||||
|
static_assert(N < sizeof...(Types), "N index out of bounds");
|
||||||
|
|
||||||
|
return do_union_get(variant_index_tag<N>{}, u);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t N, bool IsTrivial, typename...Types>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::detail::nth_type_t<N,Types...>&&
|
||||||
|
bpstd::detail::union_get(variant_union<IsTrivial,Types...>&& u)
|
||||||
|
{
|
||||||
|
static_assert(N < sizeof...(Types), "N index out of bounds");
|
||||||
|
|
||||||
|
return bpstd::move(do_union_get(variant_index_tag<N>{}, u));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t N, bool IsTrivial, typename...Types>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
const bpstd::detail::nth_type_t<N,Types...>&&
|
||||||
|
bpstd::detail::union_get(const variant_union<IsTrivial,Types...>&& u)
|
||||||
|
{
|
||||||
|
static_assert(N < sizeof...(Types), "N index out of bounds");
|
||||||
|
|
||||||
|
return bpstd::move(do_union_get(variant_index_tag<N>{}, u));
|
||||||
|
}
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE
|
||||||
|
|
||||||
|
#endif /* BPSTD_DETAIL_VARIANT_UNION_HPP */
|
195
src/libs/vmisc/bpstd/detail/variant_visitors.hpp
Normal file
195
src/libs/vmisc/bpstd/detail/variant_visitors.hpp
Normal file
|
@ -0,0 +1,195 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* \file variant_visitors.hpp
|
||||||
|
*
|
||||||
|
* \brief This internal header provides the definition of various visitors for
|
||||||
|
* the variant.
|
||||||
|
*
|
||||||
|
* These variants are used internally to construct a variant.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2020 Matthew Rodusek All rights reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef BPSTD_DETAIL_VARIANT_VISITORS_HPP
|
||||||
|
#define BPSTD_DETAIL_VARIANT_VISITORS_HPP
|
||||||
|
|
||||||
|
#include "config.hpp"
|
||||||
|
#include "move.hpp"
|
||||||
|
#include "../tuple.hpp" // get
|
||||||
|
#include "../utility.hpp" // index_sequence
|
||||||
|
|
||||||
|
#include <new> // placement new
|
||||||
|
#include <utility> // std::swap
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
|
||||||
|
|
||||||
|
namespace bpstd {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \brief A visitor for copy-constructing an underlying variant from the
|
||||||
|
/// same active type from the other variant
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
struct variant_copy_construct_visitor
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
void operator()(T& self, const T& other) const
|
||||||
|
{
|
||||||
|
new (&self) T(other);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \brief A visitor for copy-assigning an underlying variant from the
|
||||||
|
/// same active type from the other variant
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
struct variant_copy_assign_visitor
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
void operator()(T& self, const T& other) const
|
||||||
|
{
|
||||||
|
self = other;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \brief A visitor for move-constructing an underlying variant from the
|
||||||
|
/// same active type from the other variant
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
struct variant_move_construct_visitor
|
||||||
|
{
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
void operator()(T& self, U&& other) const
|
||||||
|
{
|
||||||
|
new (&self) T(bpstd::forward<U>(other));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \brief A visitor for move-assign an underlying variant from the
|
||||||
|
/// same active type from the other variant
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
struct variant_move_assign_visitor
|
||||||
|
{
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
void operator()(T& self, U&& other) const
|
||||||
|
{
|
||||||
|
self = bpstd::forward<U>(other);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \brief A visitor for swapping the underlying elements of a variant
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
struct variant_swap_visitor
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
void operator()(T& lhs, T& rhs) const
|
||||||
|
{
|
||||||
|
using std::swap;
|
||||||
|
swap(lhs,rhs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \brief A visitor for assigning an element from T to the underlying
|
||||||
|
/// active variant alternative
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename T, typename Arg>
|
||||||
|
struct variant_assign_visitor
|
||||||
|
{
|
||||||
|
Arg m_value;
|
||||||
|
|
||||||
|
template <typename UArg>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
variant_assign_visitor(UArg&& u)
|
||||||
|
: m_value(bpstd::forward<UArg>(u))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
void operator()(U&)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
void operator()(T& x)
|
||||||
|
{
|
||||||
|
x = static_cast<Arg>(m_value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \brief A visitor for emplacing elements into a variant
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename T, typename Tuple>
|
||||||
|
struct variant_emplace_visitor
|
||||||
|
{
|
||||||
|
Tuple m_tuple;
|
||||||
|
|
||||||
|
template <typename UTuple>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
variant_emplace_visitor(UTuple&& tuple)
|
||||||
|
: m_tuple{bpstd::forward<UTuple>(tuple)}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
void operator()(U&)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
void operator()(T& x)
|
||||||
|
{
|
||||||
|
emplace_from_tuple(
|
||||||
|
&x,
|
||||||
|
bpstd::move(m_tuple),
|
||||||
|
make_index_sequence<tuple_size<Tuple>::value>{}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename UTuple, std::size_t... I>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
static void emplace_from_tuple(void* p, UTuple&& tuple, index_sequence<I...>)
|
||||||
|
{
|
||||||
|
new(p) T(std::get<I>(bpstd::forward<UTuple>(tuple))...);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace bpstd
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE
|
||||||
|
|
||||||
|
#endif /* BPSTD_DETAIL_VARIANT_VISITORS_HPP */
|
199
src/libs/vmisc/bpstd/exception.hpp
Normal file
199
src/libs/vmisc/bpstd/exception.hpp
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \file exception.hpp
|
||||||
|
///
|
||||||
|
/// \brief This header provides definitions from the C++ header <exception>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2020 Matthew Rodusek All rights reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef BPSTD_EXCEPTION_HPP
|
||||||
|
#define BPSTD_EXCEPTION_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include "detail/config.hpp"
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
|
||||||
|
|
||||||
|
// The large #if/endif block below, and the definition of
|
||||||
|
// bpstd::uncaught_exceptions is taken from boost:
|
||||||
|
// https://beta.boost.org/doc/libs/develop/boost/core/uncaught_exceptions.hpp
|
||||||
|
|
||||||
|
// Copyright Andrey Semashev 2018.
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#if (__cplusplus >= 201703L && defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411) || \
|
||||||
|
defined(_MSC_VER) && _MSC_VER >= 1900
|
||||||
|
# define BPSTD_HAS_UNCAUGHT_EXCEPTIONS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(BPSTD_HAS_UNCAUGHT_EXCEPTIONS)
|
||||||
|
|
||||||
|
// cxxabi.h availability macro
|
||||||
|
# if defined(__has_include)
|
||||||
|
# if __has_include(<cxxabi.h>)
|
||||||
|
# define BPSTD_HAS_CXXABI_H
|
||||||
|
# endif
|
||||||
|
# elif defined(__GLIBCXX__) || defined(__GLIBCPP__)
|
||||||
|
# define BPSTD_HAS_CXXABI_H
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if defined(BPSTD_HAS_CXXABI_H)
|
||||||
|
// MinGW GCC 4.4 seem to not work the same way the newer GCC versions do. As
|
||||||
|
// a result, __cxa_get_globals based implementation will always return 0.
|
||||||
|
// Just disable it for now and fall back to std::uncaught_exception().
|
||||||
|
# if !(defined(__MINGW32__) && (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 405))
|
||||||
|
# include <cxxabi.h>
|
||||||
|
# include <cstring>
|
||||||
|
# define BPSTD_HAS_CXA_GET_GLOBALS
|
||||||
|
|
||||||
|
// At least on MinGW and Linux, only GCC since 4.7 declares __cxa_get_globals()
|
||||||
|
// in cxxabi.h. Older versions of GCC do not expose this function but it's
|
||||||
|
// there.
|
||||||
|
// On OpenBSD, it seems, the declaration is also missing.
|
||||||
|
// Note that at least on FreeBSD 11, cxxabi.h declares __cxa_get_globals with
|
||||||
|
// a different exception specification, so we can't declare the function
|
||||||
|
// unconditionally. On Linux with clang and libc++ and on OS X, there is a
|
||||||
|
// version of cxxabi.h from libc++abi that doesn't declare __cxa_get_globals,
|
||||||
|
// but provides __cxa_uncaught_exceptions.
|
||||||
|
// The function only appeared in version _LIBCPPABI_VERSION >= 1002 of the
|
||||||
|
// library. Unfortunately, there are linking errors about undefined reference
|
||||||
|
// to __cxa_uncaught_exceptions on Ubuntu Trusty and OS X, so we avoid using
|
||||||
|
// it and forward-declare __cxa_get_globals instead. On QNX SDP 7.0 (QCC 5.4.0),
|
||||||
|
// there are multiple cxxabi.h, one from glibcxx from gcc and another from
|
||||||
|
// libc++abi from LLVM. Which one is included will be determined by the qcc
|
||||||
|
// command line arguments (-V and/or -Y;
|
||||||
|
// http://www.qnx.com/developers/docs/7.0.0/#com.qnx.doc.neutrino.utilities/topic/q/qcc.html
|
||||||
|
// ).
|
||||||
|
// The LLVM libc++abi is missing the declaration of __cxa_get_globals but it is
|
||||||
|
// also patched by QNX developers to not define _LIBCPPABI_VERSION. Older QNX
|
||||||
|
// SDP versions, up to and including 6.6, don't provide LLVM and libc++abi.
|
||||||
|
// See https://github.com/boostorg/core/issues/59.
|
||||||
|
# if !defined(__FreeBSD__) && \
|
||||||
|
( \
|
||||||
|
(defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 407) || \
|
||||||
|
defined(__OpenBSD__) || \
|
||||||
|
(defined(__QNXNTO__) && !defined(__GLIBCXX__) && !defined(__GLIBCPP__)) || \
|
||||||
|
defined(_LIBCPPABI_VERSION) \
|
||||||
|
)
|
||||||
|
namespace __cxxabiv1 {
|
||||||
|
struct __cxa_eh_globals;
|
||||||
|
# if defined(__OpenBSD__)
|
||||||
|
extern "C" __cxa_eh_globals* __cxa_get_globals();
|
||||||
|
# else
|
||||||
|
extern "C" __cxa_eh_globals* __cxa_get_globals() noexcept __attribute__((__const__));
|
||||||
|
# endif
|
||||||
|
} // namespace __cxxabiv1
|
||||||
|
# endif
|
||||||
|
# endif // !(defined(__MINGW32__) && (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 405))
|
||||||
|
# endif // defined(BPSTD_HAS_CXXABI_H)
|
||||||
|
|
||||||
|
# if defined(_MSC_VER) && _MSC_VER >= 1400
|
||||||
|
# include <cstring>
|
||||||
|
# define BPSTD_HAS_GETPTD
|
||||||
|
namespace scope {
|
||||||
|
namespace detail {
|
||||||
|
extern "C" void* _getptd();
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace scope
|
||||||
|
# endif // defined(_MSC_VER) && _MSC_VER >= 1400
|
||||||
|
#endif // !defined(BPSTD_HAS_UNCAUGHT_EXCEPTIONS)
|
||||||
|
|
||||||
|
#if !defined(BPSTD_HAS_UNCAUGHT_EXCEPTIONS) && \
|
||||||
|
!defined(BPSTD_HAS_CXA_GET_GLOBALS) && \
|
||||||
|
!defined(BPSTD_HAS_GETPTD)
|
||||||
|
//! This macro is defined when `uncaught_exceptions` is not guaranteed to
|
||||||
|
//! return values greater than 1 if multiple exceptions are pending
|
||||||
|
# define BPSTD_UNCAUGHT_EXCEPTIONS_EMULATED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace bpstd {
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// non-member functions
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
/// \brief Returns the number of exceptions currently in-flight in the current
|
||||||
|
/// frame
|
||||||
|
///
|
||||||
|
/// \return the number of exceptions
|
||||||
|
int uncaught_exceptions() noexcept;
|
||||||
|
|
||||||
|
} // namespace bpstd
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
// definitions : non-member functions
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Utilities
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
int bpstd::uncaught_exceptions()
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
#if defined(BPSTD_HAS_UNCAUGHT_EXCEPTIONS)
|
||||||
|
// C++17 implementation
|
||||||
|
return std::uncaught_exceptions();
|
||||||
|
#elif defined(BPSTD_HAS_CXA_GET_GLOBALS)
|
||||||
|
// Tested on {clang 3.2,GCC 3.5.6,GCC 4.1.2,GCC 4.4.6,GCC 4.4.7}x{x32,x64}
|
||||||
|
using byte = unsigned char;
|
||||||
|
auto count = int{};
|
||||||
|
const auto* ptr = reinterpret_cast<const byte*>(::abi::__cxa_get_globals()) + sizeof(void*);
|
||||||
|
|
||||||
|
// __cxa_eh_globals::uncaughtExceptions, x32 offset - 0x4, x64 - 0x8
|
||||||
|
std::memcpy(&count, ptr, sizeof(count));
|
||||||
|
return count;
|
||||||
|
#elif defined(BPSTD_HAS_GETPTD)
|
||||||
|
// MSVC specific. Tested on {MSVC2005SP1,MSVC2008SP1,MSVC2010SP1,MSVC2012}x{x32,x64}.
|
||||||
|
using byte = unsigned char;
|
||||||
|
auto count = int{};
|
||||||
|
|
||||||
|
const auto offset = (sizeof(void*) == 8u ? 0x100 : 0x90);
|
||||||
|
const auto* ptr = static_cast<const byte*>(::scope::detail::_getptd()) + offset;
|
||||||
|
|
||||||
|
// _tiddata::_ProcessingThrow, x32 offset - 0x90, x64 - 0x100
|
||||||
|
std::memcpy(&count, ptr, sizeof(count));
|
||||||
|
return count;
|
||||||
|
#else
|
||||||
|
// Portable C++03 implementation. Does not allow to detect multiple
|
||||||
|
// nested exceptions.
|
||||||
|
|
||||||
|
// This is a buggy fallback since it will only work with 1 exception
|
||||||
|
// in-flight, but we don't have any other options without exploiting
|
||||||
|
// internal compiler features.
|
||||||
|
return static_cast<int>(std::uncaught_exception());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE
|
||||||
|
|
||||||
|
#endif /* BPSTD_EXCEPTION_HPP */
|
699
src/libs/vmisc/bpstd/functional.hpp
Normal file
699
src/libs/vmisc/bpstd/functional.hpp
Normal file
|
@ -0,0 +1,699 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \file functional.hpp
|
||||||
|
///
|
||||||
|
/// \brief This header provides definitions from the C++ header <functional>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2020 Matthew Rodusek All rights reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef BPSTD_FUNCTIONAL_HPP
|
||||||
|
#define BPSTD_FUNCTIONAL_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include "detail/config.hpp"
|
||||||
|
#include "type_traits.hpp"
|
||||||
|
#include "utility.hpp"
|
||||||
|
#include "detail/invoke.hpp"
|
||||||
|
|
||||||
|
#include <functional> // to proxy API
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
|
||||||
|
|
||||||
|
namespace bpstd {
|
||||||
|
|
||||||
|
/// \brief Invoke the Callable object \p function with the parameters \p args.
|
||||||
|
///
|
||||||
|
/// As by \c INVOKE(std::forward<F>(f), std::forward<Args>(args)...)
|
||||||
|
///
|
||||||
|
/// \param function Callable object to be invoked
|
||||||
|
/// \param args arguments to pass to \p function
|
||||||
|
template <typename Func, typename... Args>
|
||||||
|
constexpr invoke_result_t<Func,Args...> invoke(Func&& function, Args&&... args)
|
||||||
|
noexcept(is_nothrow_invocable<Func,Args...>::value);
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
template <typename Fn>
|
||||||
|
struct not_fn_t
|
||||||
|
{
|
||||||
|
Fn fn;
|
||||||
|
|
||||||
|
template <typename...Args>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
|
||||||
|
auto operator()(Args&&... args) &
|
||||||
|
noexcept(noexcept(!::bpstd::invoke(fn, ::bpstd::forward<Args>(args)...)))
|
||||||
|
-> decltype(!::bpstd::invoke(fn, ::bpstd::forward<Args>(args)...))
|
||||||
|
{
|
||||||
|
return !::bpstd::invoke(fn, bpstd::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename...Args>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
|
||||||
|
auto operator()(Args&&... args) &&
|
||||||
|
noexcept(noexcept(!::bpstd::invoke(std::move(fn), ::bpstd::forward<Args>(args)...)))
|
||||||
|
-> decltype(!::bpstd::invoke(std::move(fn), ::bpstd::forward<Args>(args)...))
|
||||||
|
{
|
||||||
|
return !::bpstd::invoke(std::move(fn), bpstd::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename...Args>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto operator()(Args&&... args) const&
|
||||||
|
noexcept(noexcept(!::bpstd::invoke(fn, ::bpstd::forward<Args>(args)...)))
|
||||||
|
-> decltype(!::bpstd::invoke(fn, ::bpstd::forward<Args>(args)...))
|
||||||
|
{
|
||||||
|
return !::bpstd::invoke(fn, bpstd::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename...Args>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto operator()(Args&&... args) const&&
|
||||||
|
noexcept(noexcept(!::bpstd::invoke(std::move(fn), ::bpstd::forward<Args>(args)...)))
|
||||||
|
-> decltype(!::bpstd::invoke(std::move(fn), ::bpstd::forward<Args>(args)...))
|
||||||
|
{
|
||||||
|
return !::bpstd::invoke(std::move(fn), bpstd::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/// \brief Creates a forwarding call wrapper that returns the negation of the
|
||||||
|
/// callable object it holds.
|
||||||
|
///
|
||||||
|
/// \param fn the object from which the Callable object held by the wrapper
|
||||||
|
/// is constructed
|
||||||
|
/// \return the negated object
|
||||||
|
template <typename Fn>
|
||||||
|
constexpr detail::not_fn_t<decay_t<Fn>> not_fn(Fn&& fn);
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// struct : plus
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
template <typename T = void>
|
||||||
|
struct plus
|
||||||
|
{
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
T operator()(const T& lhs, const T& rhs)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return lhs + rhs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct plus<void>
|
||||||
|
{
|
||||||
|
using is_transparent = true_type;
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto operator()(T&& lhs, U&& rhs) const
|
||||||
|
-> decltype(::bpstd::forward<T>(lhs) + ::bpstd::forward<U>(rhs))
|
||||||
|
{
|
||||||
|
return bpstd::forward<T>(lhs) + bpstd::forward<U>(rhs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// struct : minus
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
template <typename T = void>
|
||||||
|
struct minus
|
||||||
|
{
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
T operator()(const T& lhs, const T& rhs)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return lhs - rhs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct minus<void>
|
||||||
|
{
|
||||||
|
using is_transparent = true_type;
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto operator()(T&& lhs, U&& rhs) const
|
||||||
|
-> decltype(::bpstd::forward<T>(lhs) - ::bpstd::forward<U>(rhs))
|
||||||
|
{
|
||||||
|
return bpstd::forward<T>(lhs) - bpstd::forward<U>(rhs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// struct : multiplies
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
template <typename T = void>
|
||||||
|
struct multiplies
|
||||||
|
{
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
T operator()(const T& lhs, const T& rhs)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return lhs * rhs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct multiplies<void>
|
||||||
|
{
|
||||||
|
using is_transparent = true_type;
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto operator()(T&& lhs, U&& rhs) const
|
||||||
|
-> decltype(::bpstd::forward<T>(lhs) * ::bpstd::forward<U>(rhs))
|
||||||
|
{
|
||||||
|
return bpstd::forward<T>(lhs) * bpstd::forward<U>(rhs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// struct : divides
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
template <typename T = void>
|
||||||
|
struct divides
|
||||||
|
{
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
T operator()(const T& lhs, const T& rhs)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return lhs / rhs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct divides<void>
|
||||||
|
{
|
||||||
|
using is_transparent = true_type;
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto operator()(T&& lhs, U&& rhs) const
|
||||||
|
-> decltype(::bpstd::forward<T>(lhs) / ::bpstd::forward<U>(rhs))
|
||||||
|
{
|
||||||
|
return bpstd::forward<T>(lhs) / bpstd::forward<U>(rhs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// struct : modulus
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
template <typename T = void>
|
||||||
|
struct modulus
|
||||||
|
{
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
T operator()(const T& lhs, const T& rhs)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return lhs % rhs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct modulus<void>
|
||||||
|
{
|
||||||
|
using is_transparent = true_type;
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto operator()(T&& lhs, U&& rhs) const
|
||||||
|
-> decltype(::bpstd::forward<T>(lhs) % ::bpstd::forward<U>(rhs))
|
||||||
|
{
|
||||||
|
return bpstd::forward<T>(lhs) % bpstd::forward<U>(rhs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// struct : negate
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
template <typename T = void>
|
||||||
|
struct negate
|
||||||
|
{
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
T operator()(const T& arg)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return -arg;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct negate<void>
|
||||||
|
{
|
||||||
|
using is_transparent = true_type;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto operator()(T&& arg) const
|
||||||
|
-> decltype(-::bpstd::forward<T>(arg))
|
||||||
|
{
|
||||||
|
return -bpstd::forward<T>(arg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// struct : equal_to
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
template <typename T = void>
|
||||||
|
struct equal_to
|
||||||
|
{
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bool operator()(const T& lhs, const T& rhs)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return lhs == rhs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct equal_to<void>
|
||||||
|
{
|
||||||
|
using is_transparent = true_type;
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto operator()(T&& lhs, U&& rhs) const
|
||||||
|
-> decltype(::bpstd::forward<T>(lhs) == ::bpstd::forward<U>(rhs))
|
||||||
|
{
|
||||||
|
return bpstd::forward<T>(lhs) == bpstd::forward<U>(rhs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// struct : not_equal_to
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
template <typename T = void>
|
||||||
|
struct not_equal_to
|
||||||
|
{
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bool operator()(const T& lhs, const T& rhs)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return lhs != rhs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct not_equal_to<void>
|
||||||
|
{
|
||||||
|
using is_transparent = true_type;
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto operator()(T&& lhs, U&& rhs) const
|
||||||
|
-> decltype(::bpstd::forward<T>(lhs) != ::bpstd::forward<U>(rhs))
|
||||||
|
{
|
||||||
|
return bpstd::forward<T>(lhs) != bpstd::forward<U>(rhs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// struct : greater
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
template <typename T = void>
|
||||||
|
struct greater
|
||||||
|
{
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bool operator()(const T& lhs, const T& rhs)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return lhs > rhs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct greater<void>
|
||||||
|
{
|
||||||
|
using is_transparent = true_type;
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto operator()(T&& lhs, U&& rhs) const
|
||||||
|
-> decltype(::bpstd::forward<T>(lhs) > ::bpstd::forward<U>(rhs))
|
||||||
|
{
|
||||||
|
return bpstd::forward<T>(lhs) > bpstd::forward<U>(rhs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// struct : greater_equal
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
template <typename T = void>
|
||||||
|
struct greater_equal
|
||||||
|
{
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bool operator()(const T& lhs, const T& rhs)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return lhs >= rhs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct greater_equal<void>
|
||||||
|
{
|
||||||
|
using is_transparent = true_type;
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto operator()(T&& lhs, U&& rhs) const
|
||||||
|
-> decltype(::bpstd::forward<T>(lhs) >= ::bpstd::forward<U>(rhs))
|
||||||
|
{
|
||||||
|
return bpstd::forward<T>(lhs) >= bpstd::forward<U>(rhs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// struct : less
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
template <typename T = void>
|
||||||
|
struct less
|
||||||
|
{
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bool operator()(const T& lhs, const T& rhs)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return lhs < rhs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct less<void>
|
||||||
|
{
|
||||||
|
using is_transparent = true_type;
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto operator()(T&& lhs, U&& rhs) const
|
||||||
|
-> decltype(::bpstd::forward<T>(lhs) < ::bpstd::forward<U>(rhs))
|
||||||
|
{
|
||||||
|
return bpstd::forward<T>(lhs) < bpstd::forward<U>(rhs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// struct : less_equal
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
template <typename T = void>
|
||||||
|
struct less_equal
|
||||||
|
{
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bool operator()(const T& lhs, const T& rhs)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return lhs <= rhs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct less_equal<void>
|
||||||
|
{
|
||||||
|
using is_transparent = true_type;
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto operator()(T&& lhs, U&& rhs) const
|
||||||
|
-> decltype(::bpstd::forward<T>(lhs) <= ::bpstd::forward<U>(rhs))
|
||||||
|
{
|
||||||
|
return bpstd::forward<T>(lhs) <= bpstd::forward<U>(rhs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// struct : logical_and
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
template <typename T = void>
|
||||||
|
struct logical_and
|
||||||
|
{
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bool operator()(const T& lhs, const T& rhs)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return lhs && rhs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct logical_and<void>
|
||||||
|
{
|
||||||
|
using is_transparent = true_type;
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto operator()(T&& lhs, U&& rhs) const
|
||||||
|
-> decltype(::bpstd::forward<T>(lhs) && ::bpstd::forward<U>(rhs))
|
||||||
|
{
|
||||||
|
return bpstd::forward<T>(lhs) && bpstd::forward<U>(rhs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// struct : logical_or
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
template <typename T = void>
|
||||||
|
struct logical_or
|
||||||
|
{
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bool operator()(const T& lhs, const T& rhs)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return lhs || rhs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct logical_or<void>
|
||||||
|
{
|
||||||
|
using is_transparent = true_type;
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto operator()(T&& lhs, U&& rhs) const
|
||||||
|
-> decltype(::bpstd::forward<T>(lhs) || ::bpstd::forward<U>(rhs))
|
||||||
|
{
|
||||||
|
return bpstd::forward<T>(lhs) || bpstd::forward<U>(rhs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// struct : logical_not
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
template <typename T = void>
|
||||||
|
struct logical_not
|
||||||
|
{
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bool operator()(const T& arg)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return !arg;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct logical_not<void>
|
||||||
|
{
|
||||||
|
using is_transparent = true_type;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto operator()(T&& arg) const
|
||||||
|
-> decltype(!::bpstd::forward<T>(arg))
|
||||||
|
{
|
||||||
|
return !bpstd::forward<T>(arg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// struct : bit_and
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
template <typename T = void>
|
||||||
|
struct bit_and
|
||||||
|
{
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
T operator()(const T& lhs, const T& rhs)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return lhs & rhs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct bit_and<void>
|
||||||
|
{
|
||||||
|
using is_transparent = true_type;
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto operator()(T&& lhs, U&& rhs) const
|
||||||
|
-> decltype(::bpstd::forward<T>(lhs) & ::bpstd::forward<U>(rhs))
|
||||||
|
{
|
||||||
|
return bpstd::forward<T>(lhs) & bpstd::forward<U>(rhs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// struct : bit_or
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
template <typename T = void>
|
||||||
|
struct bit_or
|
||||||
|
{
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
T operator()(const T& lhs, const T& rhs)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return lhs | rhs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct bit_or<void>
|
||||||
|
{
|
||||||
|
using is_transparent = true_type;
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto operator()(T&& lhs, U&& rhs) const
|
||||||
|
-> decltype(::bpstd::forward<T>(lhs) | ::bpstd::forward<U>(rhs))
|
||||||
|
{
|
||||||
|
return bpstd::forward<T>(lhs) | bpstd::forward<U>(rhs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// struct : bit_xor
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
template <typename T = void>
|
||||||
|
struct bit_xor
|
||||||
|
{
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
T operator()(const T& lhs, const T& rhs)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return lhs ^ rhs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct bit_xor<void>
|
||||||
|
{
|
||||||
|
using is_transparent = true_type;
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto operator()(T&& lhs, U&& rhs) const
|
||||||
|
-> decltype(::bpstd::forward<T>(lhs) ^ ::bpstd::forward<U>(rhs))
|
||||||
|
{
|
||||||
|
return bpstd::forward<T>(lhs) ^ bpstd::forward<U>(rhs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// struct : bit_not
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
template <typename T = void>
|
||||||
|
struct bit_not
|
||||||
|
{
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
T operator()(const T& arg)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return ~arg;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct bit_not<void>
|
||||||
|
{
|
||||||
|
using is_transparent = true_type;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto operator()(T&& arg) const
|
||||||
|
-> decltype(~::bpstd::forward<T>(arg))
|
||||||
|
{
|
||||||
|
return ~bpstd::forward<T>(arg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace bpstd
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
// definition : invoke
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
template <typename Func, typename... Args>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::invoke_result_t<Func,Args...> bpstd::invoke(Func&& function, Args&&... args)
|
||||||
|
noexcept(is_nothrow_invocable<Func,Args...>::value)
|
||||||
|
{
|
||||||
|
return detail::INVOKE(bpstd::forward<Func>(function), bpstd::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
// definition : not_fn
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
template <typename Fn>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::detail::not_fn_t<bpstd::decay_t<Fn>> bpstd::not_fn(Fn&& fn)
|
||||||
|
{
|
||||||
|
static_assert(
|
||||||
|
is_move_constructible<Fn>::value,
|
||||||
|
"Fn must be move constructible"
|
||||||
|
);
|
||||||
|
static_assert(
|
||||||
|
is_constructible<decay_t<Fn>,Fn>::value,
|
||||||
|
"Fn must be constructible from an instance of fn"
|
||||||
|
);
|
||||||
|
|
||||||
|
return { bpstd::forward<Fn>(fn) };
|
||||||
|
}
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE
|
||||||
|
|
||||||
|
#endif /* BPSTD_FUNCTIONAL_HPP */
|
278
src/libs/vmisc/bpstd/iterator.hpp
Normal file
278
src/libs/vmisc/bpstd/iterator.hpp
Normal file
|
@ -0,0 +1,278 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \file iterator.hpp
|
||||||
|
///
|
||||||
|
/// \brief This header provides definitions from the C++ header <iterator>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2020 Matthew Rodusek All rights reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef BPSTD_ITERATOR_HPP
|
||||||
|
#define BPSTD_ITERATOR_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include "detail/config.hpp"
|
||||||
|
#include "type_traits.hpp" // common_type_t
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
#include <cstddef> // std::size_t
|
||||||
|
#include <initializer_list>
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
|
||||||
|
|
||||||
|
namespace bpstd {
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// class : reverse_iterator
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using reverse_iterator = std::reverse_iterator<T>;
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// non-member functions : class : reverse_iterator
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
/// \brief Makes a reverse_iterator given an iterator \p i
|
||||||
|
///
|
||||||
|
/// This is a convenience function template that constructs a
|
||||||
|
/// reverse_iterator for the given iterator \p i with the type deduced from
|
||||||
|
/// the type of the argument.
|
||||||
|
///
|
||||||
|
/// \param i the iterator
|
||||||
|
/// \return the reverse_iterator
|
||||||
|
template <typename Iterator>
|
||||||
|
constexpr reverse_iterator<Iterator> make_reverse_iterator(Iterator i);
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// non-member functions
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
/// \{
|
||||||
|
/// \brief Gets a pointer to the data from \p c
|
||||||
|
///
|
||||||
|
/// \param c the container to get the data pointe rrom
|
||||||
|
/// \return a pointer to the data
|
||||||
|
template <typename C>
|
||||||
|
constexpr auto data(C& c) -> decltype(c.data());
|
||||||
|
template <typename C>
|
||||||
|
constexpr auto data(const C& c) -> decltype(c.data());
|
||||||
|
/// \}
|
||||||
|
|
||||||
|
/// \brief Gets a pointer to the start of an array
|
||||||
|
///
|
||||||
|
/// \param array the array to get the pointer to
|
||||||
|
/// \return a pointer to the data
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
constexpr T* data(T (&array)[N]) noexcept;
|
||||||
|
|
||||||
|
/// \brief Gets a pointer to the start of an initializer list
|
||||||
|
///
|
||||||
|
/// \param il the initializer list
|
||||||
|
/// \return a pointer to the start of the initializer list
|
||||||
|
template <typename E>
|
||||||
|
constexpr const E* data(std::initializer_list<E> il) noexcept;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// \brief Queries whether \p c is empty
|
||||||
|
///
|
||||||
|
/// \param c the container to query
|
||||||
|
/// \return true if \p is empty
|
||||||
|
template <typename C>
|
||||||
|
constexpr auto empty(const C& c) -> decltype(c.empty());
|
||||||
|
|
||||||
|
/// \brief Queries whether the array is empty
|
||||||
|
///
|
||||||
|
/// \param array the array to check
|
||||||
|
/// \return true if N is 0
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
constexpr bool empty(const T (&array)[N]) noexcept;
|
||||||
|
|
||||||
|
/// \brief Queries whether an initializer list is empty
|
||||||
|
///
|
||||||
|
/// \param il the initializer list to check
|
||||||
|
/// \return true if \p il is empty
|
||||||
|
template <typename E>
|
||||||
|
constexpr bool empty(std::initializer_list<E> il) noexcept;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// \brief Gets the size of a container
|
||||||
|
///
|
||||||
|
/// \param c the container to check
|
||||||
|
/// \return the container's size
|
||||||
|
template <typename C>
|
||||||
|
constexpr auto size(const C& c) -> decltype(c.size());
|
||||||
|
|
||||||
|
/// \brief Gets the size of an array
|
||||||
|
///
|
||||||
|
/// \param array the array to get the size from
|
||||||
|
/// \return the size of an array
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
constexpr std::size_t size(const T (&array)[N]) noexcept;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// \brief Gets the signed-size of a container
|
||||||
|
///
|
||||||
|
/// \param c the container to get the size from
|
||||||
|
/// \return the size of the container
|
||||||
|
template <typename C>
|
||||||
|
constexpr auto ssize(const C& c)
|
||||||
|
-> common_type_t<std::ptrdiff_t, make_signed_t<decltype(c.size())>>;
|
||||||
|
|
||||||
|
/// \brief Gets the signed size of an array
|
||||||
|
///
|
||||||
|
/// \param array the array to get the size from
|
||||||
|
/// \return the size of an array
|
||||||
|
template <typename T, std::ptrdiff_t N>
|
||||||
|
constexpr std::ptrdiff_t ssize(const T (&array)[N]) noexcept;
|
||||||
|
|
||||||
|
} // namespace bpstd
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
// non-member functions : class : reverse_iterator
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Utilities
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::reverse_iterator<Iterator>
|
||||||
|
bpstd::make_reverse_iterator(Iterator i)
|
||||||
|
{
|
||||||
|
return reverse_iterator<Iterator>{i};
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
// non-member functions
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Utilities
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename C>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::data(C& c)
|
||||||
|
-> decltype(c.data())
|
||||||
|
{
|
||||||
|
return c.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename C>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::data(const C& c)
|
||||||
|
-> decltype(c.data())
|
||||||
|
{
|
||||||
|
return c.data();
|
||||||
|
}
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
T* bpstd::data(T (&array)[N])
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename E>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
const E* bpstd::data(std::initializer_list<E> il)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return il.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename C>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::empty(const C& c)
|
||||||
|
-> decltype(c.empty())
|
||||||
|
{
|
||||||
|
return c.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bool bpstd::empty(const T (&)[N])
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return N == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename E>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bool bpstd::empty(std::initializer_list<E> il)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return il.begin() == il.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename C>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::size(const C& c)
|
||||||
|
-> decltype(c.size())
|
||||||
|
{
|
||||||
|
return c.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
std::size_t bpstd::size(const T (&)[N])
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return N;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename C>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto bpstd::ssize(const C& c)
|
||||||
|
-> bpstd::common_type_t<std::ptrdiff_t, bpstd::make_signed_t<decltype(c.size())>>
|
||||||
|
{
|
||||||
|
using type = bpstd::common_type_t<std::ptrdiff_t, bpstd::make_signed_t<decltype(c.size())>>;
|
||||||
|
|
||||||
|
return static_cast<type>(c.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::ptrdiff_t N>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
std::ptrdiff_t bpstd::ssize(const T (&)[N])
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return N;
|
||||||
|
}
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE
|
||||||
|
|
||||||
|
#endif /* BPSTD_ITERATOR_HPP */
|
261
src/libs/vmisc/bpstd/memory.hpp
Normal file
261
src/libs/vmisc/bpstd/memory.hpp
Normal file
|
@ -0,0 +1,261 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \file memory.hpp
|
||||||
|
///
|
||||||
|
/// \brief This header provides definitions from the C++ header <memory>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2020 Matthew Rodusek All rights reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef BPSTD_MEMORY_HPP
|
||||||
|
#define BPSTD_MEMORY_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include "detail/config.hpp"
|
||||||
|
#include "type_traits.hpp" // conditional_t, void_t
|
||||||
|
#include "utility.hpp" // forward
|
||||||
|
|
||||||
|
#include <memory> // std::unique_ptr
|
||||||
|
#include <cstddef> // std::size_t
|
||||||
|
#include <type_traits> // std::declval
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
|
||||||
|
|
||||||
|
namespace bpstd {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
template <typename T>
|
||||||
|
struct make_unique_result
|
||||||
|
{
|
||||||
|
using object = T;
|
||||||
|
};
|
||||||
|
template <typename T>
|
||||||
|
struct make_unique_result<T[]>
|
||||||
|
{
|
||||||
|
using unbounded_array = T[];
|
||||||
|
};
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
struct make_unique_result<T[N]>
|
||||||
|
{
|
||||||
|
using bounded_array = T[N];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Constructs an object of type T and wraps it in a std::unique_ptr
|
||||||
|
///
|
||||||
|
/// Constructs a non-array type T. The arguments args are passed to the
|
||||||
|
/// constructor of T. This overload only participates in overload resolution
|
||||||
|
/// if T is not an array type.
|
||||||
|
///
|
||||||
|
/// \tparam T the type to construct
|
||||||
|
/// \param args the arguments to forward to T's constructor
|
||||||
|
/// \return the unique_ptr
|
||||||
|
template <typename T, typename...Args>
|
||||||
|
std::unique_ptr<typename detail::make_unique_result<T>::object>
|
||||||
|
make_unique(Args&&...args);
|
||||||
|
|
||||||
|
/// \brief Constructs an object of type T[] and wraps it in a std::unique_ptr
|
||||||
|
///
|
||||||
|
/// Constructs an array of unknown bound T. This overload only participates
|
||||||
|
/// in overload resolution if T is an array of unknown bound.
|
||||||
|
///
|
||||||
|
/// \tparam T the type to construct
|
||||||
|
/// \param size the size of the array
|
||||||
|
/// \return the unique_ptr
|
||||||
|
template <typename T>
|
||||||
|
std::unique_ptr<typename detail::make_unique_result<T>::unbounded_array>
|
||||||
|
make_unique(std::size_t size);
|
||||||
|
|
||||||
|
// Construction of arrays of known bound is disallowed
|
||||||
|
template <typename T>
|
||||||
|
std::unique_ptr<typename detail::make_unique_result<T>::bounded_array>
|
||||||
|
make_unique() = delete;
|
||||||
|
|
||||||
|
/// \brief Constructs an object of type T through default-initialization
|
||||||
|
/// and wraps it in a std::unique_ptr
|
||||||
|
///
|
||||||
|
/// Constructs a non-array type T. This overload only participates in
|
||||||
|
/// overload resolution if T is not an array type. The object is
|
||||||
|
/// default-initialised, which may mean it will need to be overwritten before
|
||||||
|
/// it is legal to be read
|
||||||
|
///
|
||||||
|
/// \tparam T the type to construct
|
||||||
|
/// \return the unique_ptr
|
||||||
|
template <typename T>
|
||||||
|
std::unique_ptr<typename detail::make_unique_result<T>::object>
|
||||||
|
make_unique_for_overwrite();
|
||||||
|
|
||||||
|
/// \brief Constructs an object of type T[] through default-initialization
|
||||||
|
/// and wraps it in a std::unique_ptr
|
||||||
|
///
|
||||||
|
/// Constructs an array of unknown bound T. This overload only participates
|
||||||
|
/// in overload resolution if T is an array of unknown bound. The array is
|
||||||
|
/// default-initialised, which may mean it will need to be overwritten before
|
||||||
|
/// it is legal to be read
|
||||||
|
///
|
||||||
|
/// \tparam T the type to construct
|
||||||
|
/// \return the unique_ptr
|
||||||
|
template <typename T>
|
||||||
|
std::unique_ptr<typename detail::make_unique_result<T>::unbounded_array>
|
||||||
|
make_unique_for_overwrite(std::size_t size);
|
||||||
|
|
||||||
|
// Construction of arrays of known bound is disallowed
|
||||||
|
template <typename T>
|
||||||
|
std::unique_ptr<typename detail::make_unique_result<T>::bounded_array>
|
||||||
|
make_unique_for_overwrite() = delete;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template <typename T, typename = void>
|
||||||
|
struct has_to_address : false_type{};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct has_to_address<T,void_t<decltype(std::pointer_traits<T>::to_address(std::declval<const T&>()))>>
|
||||||
|
: true_type{};
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <bool, typename T>
|
||||||
|
struct operator_deref
|
||||||
|
{
|
||||||
|
using type = decltype(std::declval<const T&>().operator->());
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct operator_deref<true, T>{};
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename T, typename = void>
|
||||||
|
struct to_address_result
|
||||||
|
: operator_deref<std::is_pointer<remove_cvref_t<T>>::value, T>{};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct to_address_result<T,void_t<decltype(std::pointer_traits<T>::to_address(std::declval<const T&>()))>>
|
||||||
|
{
|
||||||
|
using type = decltype(std::pointer_traits<T>::to_address(std::declval<const T&>()));
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using to_address_result_t = typename to_address_result<T>::type;
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/// \{
|
||||||
|
/// \brief Converts a pointer-like type to a raw pointer by recursively
|
||||||
|
/// calling to_address on it
|
||||||
|
///
|
||||||
|
/// \param p the pointer-like type
|
||||||
|
/// \return the pointer
|
||||||
|
template <typename T>
|
||||||
|
constexpr T* to_address(T* p) noexcept;
|
||||||
|
template <typename T>
|
||||||
|
constexpr detail::to_address_result_t<T> to_address(const T& p) noexcept;
|
||||||
|
/// \}
|
||||||
|
|
||||||
|
} // namespace bpstd
|
||||||
|
|
||||||
|
template <typename T, typename...Args>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
std::unique_ptr<typename bpstd::detail::make_unique_result<T>::object>
|
||||||
|
bpstd::make_unique(Args&&...args)
|
||||||
|
{
|
||||||
|
return std::unique_ptr<T>{new T(bpstd::forward<Args>(args)...)};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
std::unique_ptr<typename bpstd::detail::make_unique_result<T>::unbounded_array>
|
||||||
|
bpstd::make_unique(std::size_t size)
|
||||||
|
{
|
||||||
|
return std::unique_ptr<T>{new remove_extent_t<T>[size]()};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
std::unique_ptr<typename bpstd::detail::make_unique_result<T>::object>
|
||||||
|
bpstd::make_unique_for_overwrite()
|
||||||
|
{
|
||||||
|
return std::unique_ptr<T>{new T};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
std::unique_ptr<typename bpstd::detail::make_unique_result<T>::unbounded_array>
|
||||||
|
bpstd::make_unique_for_overwrite(std::size_t size)
|
||||||
|
{
|
||||||
|
return std::unique_ptr<T>{new remove_extent_t<T>[size]};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace bpstd {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto to_address_impl(const T& p, std::true_type)
|
||||||
|
-> decltype(std::pointer_traits<T>::to_address(std::declval<const T&>()))
|
||||||
|
{
|
||||||
|
return to_address(std::pointer_traits<T>::to_address(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
auto to_address_impl(const T& p, std::false_type)
|
||||||
|
-> decltype(std::declval<const T&>().operator->())
|
||||||
|
{
|
||||||
|
return to_address(p.operator->());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace bpstd
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
T* bpstd::to_address(T* p)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
static_assert(
|
||||||
|
!std::is_function<T>::value,
|
||||||
|
"T* must not be a function pointer"
|
||||||
|
);
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::detail::to_address_result_t<T>
|
||||||
|
bpstd::to_address(const T& p)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return detail::to_address_impl(p, detail::has_to_address<T>{});
|
||||||
|
}
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE
|
||||||
|
|
||||||
|
#endif /* BPSTD_MEMORY_HPP */
|
1774
src/libs/vmisc/bpstd/optional.hpp
Normal file
1774
src/libs/vmisc/bpstd/optional.hpp
Normal file
File diff suppressed because it is too large
Load Diff
806
src/libs/vmisc/bpstd/span.hpp
Normal file
806
src/libs/vmisc/bpstd/span.hpp
Normal file
|
@ -0,0 +1,806 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \file span.hpp
|
||||||
|
///
|
||||||
|
/// \brief This header provides definitions from the C++ header <span>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2020 Matthew Rodusek All rights reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef BPSTD_SPAN_HPP
|
||||||
|
#define BPSTD_SPAN_HPP
|
||||||
|
|
||||||
|
#include "detail/config.hpp"
|
||||||
|
#include "detail/proxy_iterator.hpp"
|
||||||
|
|
||||||
|
#include "cstddef.hpp" // byte
|
||||||
|
#include "memory.hpp" // to_address
|
||||||
|
#include "type_traits.hpp" // conjunction, remove_cvref_t, etc
|
||||||
|
|
||||||
|
#include <cstddef> // std::size_t
|
||||||
|
#include <array> // std::array
|
||||||
|
#include <iterator> // std::iterator_traits
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
|
||||||
|
|
||||||
|
namespace bpstd {
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// constants : dynamic_extent
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
BPSTD_CPP17_INLINE constexpr auto dynamic_extent = static_cast<std::size_t>(-1);
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template <std::size_t Extent>
|
||||||
|
class extent_storage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
constexpr extent_storage() noexcept = default;
|
||||||
|
|
||||||
|
template <std::size_t UExtent>
|
||||||
|
constexpr explicit extent_storage(extent_storage<UExtent>)
|
||||||
|
{
|
||||||
|
static_assert(
|
||||||
|
UExtent == Extent,
|
||||||
|
"Extent must be the same size as UExtent"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr explicit extent_storage(std::size_t)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr std::size_t size() const noexcept
|
||||||
|
{
|
||||||
|
return Extent;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class extent_storage<dynamic_extent>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template <std::size_t Extent>
|
||||||
|
constexpr explicit extent_storage(extent_storage<Extent> ext)
|
||||||
|
: m_size{ext.size()}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr explicit extent_storage(std::size_t size)
|
||||||
|
: m_size{size}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr std::size_t size() const noexcept
|
||||||
|
{
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::size_t m_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
class span_storage_type : public extent_storage<Extent>
|
||||||
|
{
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Constructors
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
public:
|
||||||
|
|
||||||
|
template <typename ExtentType>
|
||||||
|
constexpr span_storage_type(T* data, ExtentType ext)
|
||||||
|
: extent_storage<Extent>(ext),
|
||||||
|
m_data{data}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Observers
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
public:
|
||||||
|
|
||||||
|
using extent_storage<Extent>::size;
|
||||||
|
|
||||||
|
constexpr T* data() const noexcept { return m_data; }
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Private Members
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
private:
|
||||||
|
|
||||||
|
T* m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <std::size_t From, std::size_t To>
|
||||||
|
struct is_allowed_extent_conversion
|
||||||
|
: bool_constant<(From == To) || (To == dynamic_extent)>{};
|
||||||
|
|
||||||
|
template <std::size_t Extent, std::size_t Offset, std::size_t Count>
|
||||||
|
struct compute_subspan_size
|
||||||
|
: integral_constant<std::size_t,
|
||||||
|
(Count != dynamic_extent)
|
||||||
|
? Count
|
||||||
|
: ((Extent != dynamic_extent) ? (Extent - Offset) : Extent)
|
||||||
|
>{};
|
||||||
|
|
||||||
|
template <typename It>
|
||||||
|
using iter_reference = typename std::iterator_traits<It>::reference;
|
||||||
|
|
||||||
|
template <typename It, typename T>
|
||||||
|
using is_iter_convertible = conjunction<
|
||||||
|
is_same<remove_cvref_t<iter_reference<It>>,remove_cv_t<T>>,
|
||||||
|
is_convertible<iter_reference<It>,remove_cv_t<T>>
|
||||||
|
>;
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// class : span
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \brief This class is a non-owning view of a contiguous piece of memory
|
||||||
|
///
|
||||||
|
/// This type describes an object that can refer to a contiguous sequence of
|
||||||
|
/// objects with the first element of the sequence at position zero. A span
|
||||||
|
/// can either have a static extent, in which case the number of elements in
|
||||||
|
/// the sequence is known and encoded in the type, or a dynamic extent,
|
||||||
|
/// in which case the size is known at runtime.
|
||||||
|
///
|
||||||
|
/// \tparam T the underlying type of the span
|
||||||
|
/// \tparam Extent the extent (size) of the span
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename T, std::size_t Extent = dynamic_extent>
|
||||||
|
class span
|
||||||
|
{
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Public Member Types
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
public:
|
||||||
|
|
||||||
|
using element_type = T;
|
||||||
|
using value_type = remove_cv_t<T>;
|
||||||
|
using size_type = std::size_t;
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
|
||||||
|
using pointer = element_type*;
|
||||||
|
using const_pointer = const element_type*;
|
||||||
|
using reference = element_type&;
|
||||||
|
using const_reference = const element_type&;
|
||||||
|
|
||||||
|
using iterator = detail::proxy_iterator<T*,detail::span_storage_type<T,Extent>>;
|
||||||
|
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Public Member Constants
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
public:
|
||||||
|
|
||||||
|
BPSTD_CPP17_INLINE static constexpr std::size_t extent = Extent;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Constructors / Assignment
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// \brief Default-constructs a span
|
||||||
|
///
|
||||||
|
/// This constructor only participates in overload resolution if the span
|
||||||
|
/// either is size 0, or has a dynamic extent
|
||||||
|
template <std::size_t UExtent = Extent,
|
||||||
|
typename = enable_if_t<detail::is_allowed_extent_conversion<0,UExtent>::value>>
|
||||||
|
constexpr span() noexcept;
|
||||||
|
|
||||||
|
/// \{
|
||||||
|
/// \brief Constructs a span from an iterator \p it and the \p count
|
||||||
|
///
|
||||||
|
/// This constructor only participates in overload resolution if the
|
||||||
|
/// following criteria are met:
|
||||||
|
/// * Extent is dynamic_extent
|
||||||
|
/// * to_address(it) is convertible to T*
|
||||||
|
///
|
||||||
|
/// This constructor is explicit if `Extent` != `dynamic_extent`
|
||||||
|
///
|
||||||
|
/// \param it the iterator
|
||||||
|
/// \param count the number of entries in the sequence
|
||||||
|
template <typename It,
|
||||||
|
enable_if_t<(Extent == bpstd::dynamic_extent) &&
|
||||||
|
bpstd::detail::is_iter_convertible<It, T>::value,int> = 0>
|
||||||
|
constexpr span(It it, size_type count) noexcept;
|
||||||
|
template <typename It,
|
||||||
|
enable_if_t<(Extent != bpstd::dynamic_extent) &&
|
||||||
|
bpstd::detail::is_iter_convertible<It, T>::value,int> = 0>
|
||||||
|
constexpr explicit span(It it, size_type count) noexcept;
|
||||||
|
/// \}
|
||||||
|
|
||||||
|
/// \brief Constructs a span from an iterator range
|
||||||
|
///
|
||||||
|
/// This constructor only participates in overload resolution if the
|
||||||
|
/// following criteria are met:
|
||||||
|
/// * Extent is dynamic_extent
|
||||||
|
/// * to_address(it) is convertible to T*
|
||||||
|
///
|
||||||
|
/// \param it the iterator
|
||||||
|
/// \param end the end iterator
|
||||||
|
template <typename It, typename End,
|
||||||
|
enable_if_t<(Extent == bpstd::dynamic_extent) &&
|
||||||
|
bpstd::detail::is_iter_convertible<It, T>::value, int> = 0>
|
||||||
|
constexpr span(It it, End end) noexcept;
|
||||||
|
template <typename It, typename End,
|
||||||
|
enable_if_t<(Extent != bpstd::dynamic_extent) &&
|
||||||
|
bpstd::detail::is_iter_convertible<It, T>::value, int> = 0>
|
||||||
|
constexpr explicit span(It it, End end) noexcept;
|
||||||
|
|
||||||
|
/// \brief Constructs a span from an array reference
|
||||||
|
///
|
||||||
|
/// This constructor only participates in overload resolution if any of the
|
||||||
|
/// following criteria are met:
|
||||||
|
/// * Extent is dynamic_extent
|
||||||
|
/// * N is the same as Extent
|
||||||
|
///
|
||||||
|
/// \param arr the array reference
|
||||||
|
template <std::size_t N,
|
||||||
|
typename = enable_if_t<detail::is_allowed_extent_conversion<N,Extent>::value>>
|
||||||
|
// cppcheck-suppress noExplicitConstructor
|
||||||
|
constexpr span(element_type (&arr)[N]) noexcept;
|
||||||
|
|
||||||
|
/// \{
|
||||||
|
/// \brief Constructs a span from a reference to a std::array
|
||||||
|
///
|
||||||
|
/// This constructor only participates in overload resolution if the
|
||||||
|
/// following criteria are met:
|
||||||
|
/// * Extent is dynamic_extent or N is the same as Extent
|
||||||
|
/// * U is at most a cv-qualification difference from T
|
||||||
|
///
|
||||||
|
/// \param arr the array reference
|
||||||
|
template <typename U, std::size_t N,
|
||||||
|
typename = enable_if_t<detail::is_allowed_extent_conversion<N,Extent>::value>>
|
||||||
|
// cppcheck-suppress noExplicitConstructor
|
||||||
|
constexpr span(std::array<U, N>& arr) noexcept;
|
||||||
|
template <typename U, std::size_t N,
|
||||||
|
typename = enable_if_t<detail::is_allowed_extent_conversion<N,Extent>::value>>
|
||||||
|
// cppcheck-suppress noExplicitConstructor
|
||||||
|
constexpr span(const std::array<U, N>& arr) noexcept;
|
||||||
|
/// \}
|
||||||
|
|
||||||
|
// range-constructor omitted since ranges are not part of backport yet
|
||||||
|
|
||||||
|
/// \brief Constructs a span from a different span
|
||||||
|
///
|
||||||
|
/// This constructor only participates in overload resolution if the
|
||||||
|
/// following criteria are met:
|
||||||
|
/// * Extent is dynamic_extent or N is the same as Extent
|
||||||
|
/// * U is at most a cv-qualification difference from T
|
||||||
|
///
|
||||||
|
/// \param s the span
|
||||||
|
template <typename U, std::size_t N,
|
||||||
|
typename = enable_if_t<detail::is_allowed_extent_conversion<N,Extent>::value>>
|
||||||
|
// cppcheck-suppress noExplicitConstructor
|
||||||
|
constexpr span(const span<U, N>& s) noexcept;
|
||||||
|
|
||||||
|
/// \brief Constructs a span by copying \p other
|
||||||
|
///
|
||||||
|
/// \param other the other span to copy
|
||||||
|
constexpr span(const span& other) noexcept = default;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// \brief Assigns a span from \p other
|
||||||
|
///
|
||||||
|
/// \param other the other span to copy
|
||||||
|
/// \return reference to this
|
||||||
|
BPSTD_CPP14_CONSTEXPR span& operator=(const span& other) noexcept = default;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Element Access
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// \brief Gets a reference to the front element of this span
|
||||||
|
///
|
||||||
|
/// \pre empty() is false
|
||||||
|
/// \return reference to front element
|
||||||
|
constexpr reference front() const noexcept;
|
||||||
|
|
||||||
|
/// \brief Gets a reference to the back element of this span
|
||||||
|
///
|
||||||
|
/// \pre empty() is false
|
||||||
|
/// \return reference to back element
|
||||||
|
constexpr reference back() const noexcept;
|
||||||
|
|
||||||
|
/// \brief Gets a reference to the element at \p idx
|
||||||
|
///
|
||||||
|
/// \pre \p idx is less than size()
|
||||||
|
/// \param idx the index
|
||||||
|
/// \return reference to the element at \p idx
|
||||||
|
constexpr reference operator[](size_type idx) const noexcept;
|
||||||
|
|
||||||
|
/// \brief Gets a pointer to the start of the data
|
||||||
|
///
|
||||||
|
/// \return pointer to the data
|
||||||
|
constexpr pointer data() const noexcept;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Observers
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// \brief Gets the number of elements in this span
|
||||||
|
///
|
||||||
|
/// \return the number of elements in this span
|
||||||
|
constexpr size_type size() const noexcept;
|
||||||
|
|
||||||
|
/// \brief Gets the number of bytes in this span
|
||||||
|
///
|
||||||
|
/// \return the number of bytes in this span
|
||||||
|
constexpr size_type size_bytes() const noexcept;
|
||||||
|
|
||||||
|
/// \brief Queries whether this span is empty
|
||||||
|
///
|
||||||
|
/// \return true if this span is empty
|
||||||
|
constexpr bool empty() const noexcept;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Subviews
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// \brief Creates a subspan from the first \p Count elements
|
||||||
|
///
|
||||||
|
/// \pre A program is ill-formed if \p Count > Extent
|
||||||
|
///
|
||||||
|
/// \tparam Count the number of elements to create in the subspan
|
||||||
|
/// \return the first \p Count elements
|
||||||
|
template <std::size_t Count>
|
||||||
|
constexpr span<element_type, Count> first() const;
|
||||||
|
|
||||||
|
/// \brief Creates a subspan from the first \p count elements
|
||||||
|
///
|
||||||
|
/// \pre It is undefined behavior if \p count > size()
|
||||||
|
///
|
||||||
|
/// \param count the number of elements to create in the subspan
|
||||||
|
/// \return the first \p count elements
|
||||||
|
constexpr span<element_type> first(size_t count) const;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// \brief Creates a subspan from the last \p Count elements
|
||||||
|
///
|
||||||
|
/// \pre A program is ill-formed if \p Count > Extent
|
||||||
|
///
|
||||||
|
/// \tparam Count the number of elements to create in the subspan
|
||||||
|
/// \return the last \p Count elements
|
||||||
|
template <std::size_t Count>
|
||||||
|
constexpr span<element_type, Count> last() const;
|
||||||
|
|
||||||
|
/// \brief Creates a subspan from the last \p count elements
|
||||||
|
///
|
||||||
|
/// \pre It is undefined behavior if \p count > size()
|
||||||
|
///
|
||||||
|
/// \param count the number of elements to create in the subspan
|
||||||
|
/// \return the last \p count elements
|
||||||
|
constexpr span<element_type> last(size_t count) const;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// \brief Creates a subspan that is \p Count elements long, \p Offset from
|
||||||
|
/// the start of this span
|
||||||
|
///
|
||||||
|
/// \tparam Offset the amount to offset the span by
|
||||||
|
/// \tparam Count the number of elements to create in the subspan
|
||||||
|
/// \return the created subspan
|
||||||
|
template <std::size_t Offset, std::size_t Count = dynamic_extent>
|
||||||
|
constexpr span<element_type, detail::compute_subspan_size<Extent,Offset,Count>::value>
|
||||||
|
subspan() const;
|
||||||
|
|
||||||
|
/// \brief Creates a subspan that is \p count elements long, \p offset from
|
||||||
|
/// the start of this span
|
||||||
|
///
|
||||||
|
/// \param offset the amount to offset the span by
|
||||||
|
/// \param count the number of elements to create in the subspan
|
||||||
|
/// \return the created subspan
|
||||||
|
constexpr span<element_type> subspan(std::size_t offset,
|
||||||
|
std::size_t count = dynamic_extent) const;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Iterators
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
public:
|
||||||
|
|
||||||
|
constexpr iterator begin() const noexcept;
|
||||||
|
constexpr iterator end() const noexcept;
|
||||||
|
constexpr reverse_iterator rbegin() const noexcept;
|
||||||
|
constexpr reverse_iterator rend() const noexcept;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Private Members
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
private:
|
||||||
|
|
||||||
|
using storage_type = detail::span_storage_type<element_type,Extent>;
|
||||||
|
|
||||||
|
storage_type m_storage;
|
||||||
|
};
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// non-member functions : class : span
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Utilities
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// \brief Converts a span \p s to a byte span
|
||||||
|
///
|
||||||
|
/// \param s the span to convert
|
||||||
|
/// \return a span of the byte range that \p s covered
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
span<const byte, sizeof(T) * N> as_bytes(span<T, N> s) noexcept;
|
||||||
|
|
||||||
|
/// \brief Converts a span \p s to a writable byte span
|
||||||
|
///
|
||||||
|
/// \param s the span to convert
|
||||||
|
/// \return a span of the byte range that \p s covered
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
span<byte, sizeof(T) * N> as_writable_bytes(span<T, N> s) noexcept;
|
||||||
|
|
||||||
|
} // namespace bpstd
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
constexpr std::size_t bpstd::span<T,Extent>::extent;
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
// non-member functions : class : span
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Constructors
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
template <std::size_t UExtent, typename>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::span<T,Extent>::span()
|
||||||
|
noexcept
|
||||||
|
: m_storage{nullptr, detail::extent_storage<0>{}}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
template <typename It,
|
||||||
|
bpstd::enable_if_t<(Extent == bpstd::dynamic_extent) &&
|
||||||
|
bpstd::detail::is_iter_convertible<It, T>::value,int>>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::span<T,Extent>::span(It it, size_type count)
|
||||||
|
noexcept
|
||||||
|
: m_storage{to_address(it), count}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
template <typename It,
|
||||||
|
bpstd::enable_if_t<(Extent != bpstd::dynamic_extent) &&
|
||||||
|
bpstd::detail::is_iter_convertible<It, T>::value,int>>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::span<T,Extent>::span(It it, size_type count)
|
||||||
|
noexcept
|
||||||
|
: m_storage{to_address(it), count}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
template <typename It, typename End,
|
||||||
|
bpstd::enable_if_t<(Extent == bpstd::dynamic_extent) &&
|
||||||
|
bpstd::detail::is_iter_convertible<It, T>::value, int>>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::span<T,Extent>::span(It it, End end)
|
||||||
|
noexcept
|
||||||
|
: m_storage{to_address(it), static_cast<size_type>(end - it)}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
template <typename It, typename End,
|
||||||
|
bpstd::enable_if_t<(Extent != bpstd::dynamic_extent) &&
|
||||||
|
bpstd::detail::is_iter_convertible<It, T>::value, int>>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::span<T,Extent>::span(It it, End end)
|
||||||
|
noexcept
|
||||||
|
: m_storage{to_address(it), static_cast<size_type>(end - it)}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
template <std::size_t N, typename>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::span<T,Extent>::span(element_type (&arr)[N])
|
||||||
|
noexcept
|
||||||
|
: m_storage{static_cast<element_type*>(arr), detail::extent_storage<N>{}}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
template <typename U, std::size_t N, typename>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::span<T,Extent>::span(std::array<U, N>& arr)
|
||||||
|
noexcept
|
||||||
|
: m_storage{arr.data(), detail::extent_storage<N>{}}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
template <typename U, std::size_t N, typename>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::span<T,Extent>::span(const std::array<U, N>& arr)
|
||||||
|
noexcept
|
||||||
|
: m_storage{arr.data(), detail::extent_storage<N>{}}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
template <typename U, std::size_t N, typename>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::span<T,Extent>::span(const span<U, N>& s)
|
||||||
|
noexcept
|
||||||
|
: m_storage{s.data(), detail::extent_storage<N>{s.size()}}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Element Access
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
typename bpstd::span<T,Extent>::reference
|
||||||
|
bpstd::span<T,Extent>::front()
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
return data()[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
typename bpstd::span<T,Extent>::reference
|
||||||
|
bpstd::span<T,Extent>::back()
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
return data()[m_storage.size()-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
typename bpstd::span<T,Extent>::reference
|
||||||
|
bpstd::span<T,Extent>::operator[](size_type idx)
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
return data()[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
typename bpstd::span<T,Extent>::pointer
|
||||||
|
bpstd::span<T,Extent>::data()
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
return m_storage.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Observers
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
typename bpstd::span<T,Extent>::size_type
|
||||||
|
bpstd::span<T,Extent>::size()
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
return m_storage.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
typename bpstd::span<T,Extent>::size_type
|
||||||
|
bpstd::span<T,Extent>::size_bytes()
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
return size() * sizeof(T);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bool bpstd::span<T,Extent>::empty()
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
return size() == 0u;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Subviews
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
template <std::size_t Count>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::span<typename bpstd::span<T, Extent>::element_type, Count>
|
||||||
|
bpstd::span<T, Extent>::first()
|
||||||
|
const
|
||||||
|
{
|
||||||
|
static_assert(
|
||||||
|
Count <= Extent,
|
||||||
|
"A Count larger than Extent is ill-formed"
|
||||||
|
);
|
||||||
|
|
||||||
|
return span<element_type, Count>{data(), Count};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::span<typename bpstd::span<T, Extent>::element_type>
|
||||||
|
bpstd::span<T,Extent>::first(size_t count)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return {data(), count};
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
template <std::size_t Count>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::span<typename bpstd::span<T, Extent>::element_type, Count>
|
||||||
|
bpstd::span<T, Extent>::last()
|
||||||
|
const
|
||||||
|
{
|
||||||
|
static_assert(
|
||||||
|
Count <= Extent,
|
||||||
|
"A Count larger than Extent is ill-formed"
|
||||||
|
);
|
||||||
|
|
||||||
|
return span<element_type, Count>{data() + (size() - Count), Count};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::span<typename bpstd::span<T, Extent>::element_type>
|
||||||
|
bpstd::span<T,Extent>::last(size_t count)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return {data() + (size() - count), count};
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
template <std::size_t Offset, std::size_t Count>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::span<typename bpstd::span<T, Extent>::element_type, bpstd::detail::compute_subspan_size<Extent,Offset,Count>::value>
|
||||||
|
bpstd::span<T, Extent>::subspan()
|
||||||
|
const
|
||||||
|
{
|
||||||
|
using result_type = span<
|
||||||
|
element_type,
|
||||||
|
detail::compute_subspan_size<Extent,Offset,Count>::value
|
||||||
|
>;
|
||||||
|
|
||||||
|
return result_type{
|
||||||
|
data() + Offset,
|
||||||
|
(Count == dynamic_extent) ? (size() - Offset) : Count
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::span<typename bpstd::span<T, Extent>::element_type>
|
||||||
|
bpstd::span<T, Extent>::subspan(std::size_t offset, std::size_t count)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
data() + offset,
|
||||||
|
(count == dynamic_extent) ? (size() - offset) : count
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Iterators
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
typename bpstd::span<T,Extent>::iterator
|
||||||
|
bpstd::span<T,Extent>::begin()
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
return iterator{data()};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
typename bpstd::span<T,Extent>::iterator
|
||||||
|
bpstd::span<T,Extent>::end()
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
return iterator{data() + size()};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
typename bpstd::span<T,Extent>::reverse_iterator
|
||||||
|
bpstd::span<T,Extent>::rbegin()
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
return reverse_iterator(end());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t Extent>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
typename bpstd::span<T,Extent>::reverse_iterator
|
||||||
|
bpstd::span<T,Extent>::rend()
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
return reverse_iterator(begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
// non-member functions : class : span
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Utilities
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
inline bpstd::span<const bpstd::byte, sizeof(T) * N> bpstd::as_bytes(span<T, N> s)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return {reinterpret_cast<const byte*>(s.data()), s.size_bytes()};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
inline bpstd::span<bpstd::byte, sizeof(T) * N> bpstd::as_writable_bytes(span<T, N> s)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return {reinterpret_cast<byte*>(s.data()), s.size_bytes()};
|
||||||
|
}
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE
|
||||||
|
|
||||||
|
#endif /* BPSTD_SPAN_HPP */
|
84
src/libs/vmisc/bpstd/string.hpp
Normal file
84
src/libs/vmisc/bpstd/string.hpp
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \file string.hpp
|
||||||
|
///
|
||||||
|
/// \brief This header provides definitions from the C++ header <string>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2020 Matthew Rodusek All rights reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef BPSTD_STRING_HPP
|
||||||
|
#define BPSTD_STRING_HPP
|
||||||
|
|
||||||
|
#include "detail/config.hpp"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
|
||||||
|
|
||||||
|
namespace bpstd {
|
||||||
|
|
||||||
|
inline namespace literals {
|
||||||
|
inline namespace string_literals {
|
||||||
|
|
||||||
|
std::string operator""_s(const char* s, std::size_t len);
|
||||||
|
std::u16string operator""_s(const char16_t* s, std::size_t len);
|
||||||
|
std::u32string operator""_s(const char32_t* s, std::size_t len);
|
||||||
|
std::wstring operator""_s(const wchar_t* s, std::size_t len);
|
||||||
|
|
||||||
|
} // inline namespace string_literals
|
||||||
|
} // inline namespace literals
|
||||||
|
|
||||||
|
} // namespace bpstd
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
std::string
|
||||||
|
bpstd::literals::string_literals::operator""_s(const char* s, std::size_t len)
|
||||||
|
{
|
||||||
|
return std::string{s, len};
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
std::u16string
|
||||||
|
bpstd::literals::string_literals::operator""_s(const char16_t* s, std::size_t len)
|
||||||
|
{
|
||||||
|
return std::u16string{s, len};
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
std::u32string
|
||||||
|
bpstd::literals::string_literals::operator""_s(const char32_t* s, std::size_t len)
|
||||||
|
{
|
||||||
|
return std::u32string{s, len};
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BPSTD_INLINE_VISIBILITY
|
||||||
|
std::wstring
|
||||||
|
bpstd::literals::string_literals::operator""_s(const wchar_t* s, std::size_t len)
|
||||||
|
{
|
||||||
|
return std::wstring{s, len};
|
||||||
|
}
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE
|
||||||
|
|
||||||
|
#endif /* BPSTD_STRING_HPP */
|
1529
src/libs/vmisc/bpstd/string_view.hpp
Normal file
1529
src/libs/vmisc/bpstd/string_view.hpp
Normal file
File diff suppressed because it is too large
Load Diff
293
src/libs/vmisc/bpstd/tuple.hpp
Normal file
293
src/libs/vmisc/bpstd/tuple.hpp
Normal file
|
@ -0,0 +1,293 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \file tuple.hpp
|
||||||
|
///
|
||||||
|
/// \brief This header provides definitions from the C++ header <tuple>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2020 Matthew Rodusek All rights reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef BPSTD_TUPLE_HPP
|
||||||
|
#define BPSTD_TUPLE_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include "type_traits.hpp" // invoke_result
|
||||||
|
#include "utility.hpp" // index_sequence, forward
|
||||||
|
#include "functional.hpp" // invoke
|
||||||
|
|
||||||
|
#include <tuple> // std::tuple_element, and to proxy API
|
||||||
|
#include <cstddef> // std::size_t
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
|
||||||
|
|
||||||
|
namespace bpstd {
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// class : tuple
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
template <typename...Types>
|
||||||
|
using tuple = std::tuple<Types...>;
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// utilities : tuple
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
template <std::size_t I, typename T>
|
||||||
|
using tuple_element = std::tuple_element<I,T>;
|
||||||
|
|
||||||
|
template <std::size_t I, typename T>
|
||||||
|
using tuple_element_t = typename tuple_element<I, T>::type;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using tuple_size = std::tuple_size<T>;
|
||||||
|
|
||||||
|
#if BPSTD_HAS_TEMPLATE_VARIABLES
|
||||||
|
template <typename T>
|
||||||
|
BPSTD_CPP17_INLINE constexpr auto tuple_size_v = tuple_size<T>::value;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// non-member functions : class : tuple
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Utilities
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
template <typename T>
|
||||||
|
struct is_tuple : false_type{};
|
||||||
|
|
||||||
|
template <typename...Types>
|
||||||
|
struct is_tuple<std::tuple<Types...>> : true_type{};
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template <std::size_t N, typename Tuple,
|
||||||
|
typename = enable_if_t<detail::is_tuple<remove_cvref_t<Tuple>>::value && is_lvalue_reference<Tuple>::value>>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
|
||||||
|
tuple_element_t<N,remove_reference_t<Tuple>>&
|
||||||
|
get(Tuple&& t) noexcept
|
||||||
|
{
|
||||||
|
return std::get<N>(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t N, typename Tuple,
|
||||||
|
typename = enable_if_t<detail::is_tuple<remove_cvref_t<Tuple>>::value && !is_lvalue_reference<Tuple>::value>>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
|
||||||
|
tuple_element_t<N,remove_reference_t<Tuple>>&&
|
||||||
|
get(Tuple&& t) noexcept
|
||||||
|
{
|
||||||
|
return bpstd::move(std::get<N>(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename... Types>
|
||||||
|
BPSTD_CPP14_CONSTEXPR T& get(tuple<Types...>& t) noexcept;
|
||||||
|
template <typename T, typename... Types>
|
||||||
|
BPSTD_CPP14_CONSTEXPR T&& get(tuple<Types...>&& t) noexcept;
|
||||||
|
template <typename T, typename... Types>
|
||||||
|
BPSTD_CPP14_CONSTEXPR const T& get(const tuple<Types...>& t) noexcept;
|
||||||
|
template <typename T, typename... Types>
|
||||||
|
BPSTD_CPP14_CONSTEXPR const T&& get(const tuple<Types...>&& t) noexcept;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
// primary template left undefined
|
||||||
|
template <typename Fn, typename Seq, typename Tuple>
|
||||||
|
struct apply_result_impl;
|
||||||
|
|
||||||
|
template <typename Fn, std::size_t...Idx, typename Tuple>
|
||||||
|
struct apply_result_impl<Fn, index_sequence<Idx...>, Tuple>
|
||||||
|
: invoke_result<Fn, tuple_element_t<Idx, Tuple>...>{};
|
||||||
|
|
||||||
|
template <typename Fn, typename Tuple>
|
||||||
|
struct apply_result : apply_result_impl<
|
||||||
|
Fn,
|
||||||
|
make_index_sequence<tuple_size<remove_reference_t<Tuple>>::value>,
|
||||||
|
Tuple
|
||||||
|
>{};
|
||||||
|
|
||||||
|
template <typename Fn, typename Tuple>
|
||||||
|
using apply_result_t = typename apply_result<Fn, Tuple>::type;
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/// \brief Invokes the function \p fn using the arguments in \p tuple
|
||||||
|
///
|
||||||
|
/// This invokes \p fn as if it were a call to bpstd::invoke using the
|
||||||
|
/// arguments in \p tuple
|
||||||
|
///
|
||||||
|
/// \param fn the function to invoke
|
||||||
|
/// \param tuple the tuple of arguments to pass to fn
|
||||||
|
/// \return the result from \p fn
|
||||||
|
template <typename Fn, typename Tuple>
|
||||||
|
constexpr detail::apply_result_t<Fn, Tuple> apply(Fn&& fn, Tuple&& tuple);
|
||||||
|
|
||||||
|
/// \brief Constructs a type \p T using the arguments in \p tuple
|
||||||
|
///
|
||||||
|
/// \tparam T the type to construct
|
||||||
|
/// \param tuple the tuple of arguments to pass to T's constructor
|
||||||
|
template <typename T, typename Tuple>
|
||||||
|
constexpr T make_from_tuple(Tuple&& tuple);
|
||||||
|
|
||||||
|
} // namespace bpstd
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
// definitions : non-member functions : class : tuple
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Utilities
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace bpstd { namespace detail {
|
||||||
|
|
||||||
|
template <typename T, std::size_t Index, typename...Types>
|
||||||
|
struct index_of_impl;
|
||||||
|
|
||||||
|
template <typename T, std::size_t Index, typename Type0, typename...Types>
|
||||||
|
struct index_of_impl<T, Index, Type0, Types...>
|
||||||
|
: index_of_impl<T, Index + 1, Types...>{};
|
||||||
|
|
||||||
|
template <typename T, std::size_t Index, typename...Types>
|
||||||
|
struct index_of_impl<T, Index, T, Types...>
|
||||||
|
: integral_constant<std::size_t, Index>{};
|
||||||
|
|
||||||
|
template <typename T, typename...Types>
|
||||||
|
struct index_of : index_of_impl<T,0,Types...>{};
|
||||||
|
|
||||||
|
}} // namespace bpstd::detail
|
||||||
|
|
||||||
|
template <typename T, typename... Types>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
|
||||||
|
T& bpstd::get(tuple<Types...>& t)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return std::get<detail::index_of<T,Types...>::value>(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename... Types>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
|
||||||
|
T&& bpstd::get(tuple<Types...>&& t)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return move(std::get<detail::index_of<T,Types...>::value>(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename... Types>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
|
||||||
|
const T& bpstd::get(const tuple<Types...>& t)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return std::get<detail::index_of<T,Types...>::value>(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename... Types>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
|
||||||
|
const T&& bpstd::get(const tuple<Types...>&& t)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return move(std::get<detail::index_of<T,Types...>::value>(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
// definition : apply
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma warning(push)
|
||||||
|
# pragma warning(disable:4100) // MSVC warns that 'tuple' is not used below
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace bpstd {
|
||||||
|
namespace detail {
|
||||||
|
template <typename Fn, typename Tuple, std::size_t... I>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
apply_result_t<Fn,Tuple> apply_impl(Fn&& fn, Tuple&& tuple, index_sequence<I...>)
|
||||||
|
{
|
||||||
|
return ::bpstd::invoke(
|
||||||
|
bpstd::forward<Fn>(fn),
|
||||||
|
std::get<I>(bpstd::forward<Tuple>(tuple))...
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace bpstd
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <typename Fn, typename Tuple>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::detail::apply_result_t<Fn, Tuple> bpstd::apply(Fn&& fn, Tuple&& tuple)
|
||||||
|
{
|
||||||
|
return detail::apply_impl(
|
||||||
|
bpstd::forward<Fn>(fn),
|
||||||
|
bpstd::forward<Tuple>(tuple),
|
||||||
|
make_index_sequence<tuple_size<remove_reference_t<Tuple>>::value>{}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
// definition : make_from_tuple
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma warning(push)
|
||||||
|
# pragma warning(disable:4100) // MSVC warns that 'tuple' is not used below
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace bpstd {
|
||||||
|
namespace detail {
|
||||||
|
template <typename T, typename Tuple, std::size_t... I>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
T make_from_tuple_impl(Tuple&& tuple, index_sequence<I...>)
|
||||||
|
{
|
||||||
|
return T(std::get<I>(bpstd::forward<Tuple>(tuple))...);
|
||||||
|
}
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace bpstd
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <typename T, typename Tuple>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
T bpstd::make_from_tuple(Tuple&& tuple)
|
||||||
|
{
|
||||||
|
return detail::make_from_tuple_impl<T>(
|
||||||
|
bpstd::forward<Tuple>(tuple),
|
||||||
|
make_index_sequence<tuple_size<remove_reference_t<Tuple>>::value>{}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE
|
||||||
|
|
||||||
|
#endif /* BPSTD_TUPLE_HPP */
|
1398
src/libs/vmisc/bpstd/type_traits.hpp
Normal file
1398
src/libs/vmisc/bpstd/type_traits.hpp
Normal file
File diff suppressed because it is too large
Load Diff
382
src/libs/vmisc/bpstd/utility.hpp
Normal file
382
src/libs/vmisc/bpstd/utility.hpp
Normal file
|
@ -0,0 +1,382 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// \file utility.hpp
|
||||||
|
///
|
||||||
|
/// \brief This header provides definitions from the C++ header <utility>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2020 Matthew Rodusek All rights reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef BPSTD_UTILITY_HPP
|
||||||
|
#define BPSTD_UTILITY_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include "detail/config.hpp"
|
||||||
|
#include "detail/move.hpp" // IWYU pragma: export
|
||||||
|
#include "type_traits.hpp" // add_const_t
|
||||||
|
|
||||||
|
#include <utility> // to proxy the API
|
||||||
|
#include <cstddef> // std::size_t
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
|
||||||
|
|
||||||
|
namespace bpstd {
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// struct : in_place_t
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
/// \brief This function is a special disambiguation tag for variadic
|
||||||
|
/// functions, used in any and optional
|
||||||
|
///
|
||||||
|
/// \note Calling this function results in undefined behaviour.
|
||||||
|
struct in_place_t
|
||||||
|
{
|
||||||
|
explicit in_place_t() = default;
|
||||||
|
};
|
||||||
|
BPSTD_CPP17_INLINE constexpr in_place_t in_place{};
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// in_place_type_t
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
/// \brief This function is a special disambiguation tag for variadic
|
||||||
|
/// functions, used in any and optional
|
||||||
|
///
|
||||||
|
/// \note Calling this function results in undefined behaviour.
|
||||||
|
template<typename T>
|
||||||
|
struct in_place_type_t
|
||||||
|
{
|
||||||
|
explicit in_place_type_t() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if BPSTD_HAS_TEMPLATE_VARIABLES
|
||||||
|
template<typename T>
|
||||||
|
BPSTD_CPP17_INLINE constexpr in_place_type_t<T> in_place_type{};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// in_place_index_t
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
/// \brief This function is a special disambiguation tag for variadic
|
||||||
|
/// functions, used in any and optional
|
||||||
|
///
|
||||||
|
/// \note Calling this function results in undefined behaviour.
|
||||||
|
template<std::size_t I> struct in_place_index_t
|
||||||
|
{
|
||||||
|
explicit in_place_index_t() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if BPSTD_HAS_TEMPLATE_VARIABLES
|
||||||
|
template<std::size_t I>
|
||||||
|
BPSTD_CPP17_INLINE constexpr in_place_index_t<I> in_place_index{};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// non-member functions
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Utilities
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// \brief Moves a type \p x if it move-construction is non-throwing
|
||||||
|
///
|
||||||
|
/// \param x the parameter to move
|
||||||
|
/// \return an rvalue reference if nothrow moveable, const reference otherwise
|
||||||
|
template <typename T>
|
||||||
|
constexpr typename bpstd::conditional<
|
||||||
|
!bpstd::is_nothrow_move_constructible<T>::value && bpstd::is_copy_constructible<T>::value,
|
||||||
|
const T&,
|
||||||
|
T&&
|
||||||
|
>::type move_if_noexcept(T& x) noexcept;
|
||||||
|
|
||||||
|
/// \brief Forms an lvalue reference to const type of t
|
||||||
|
///
|
||||||
|
/// \param t the type to form an lvalue reference to
|
||||||
|
/// \return the reference to const T
|
||||||
|
template <typename T>
|
||||||
|
constexpr add_const_t<T>& as_const(T& t) noexcept;
|
||||||
|
template <typename T>
|
||||||
|
void as_const(const T&&) = delete;
|
||||||
|
|
||||||
|
/// \brief Replaces the value of obj with new_value and returns the old value
|
||||||
|
/// of obj.
|
||||||
|
///
|
||||||
|
/// \pre \p T must meet the requirements of MoveConstructible.
|
||||||
|
///
|
||||||
|
/// \pre It must be possible to move-assign objects of type \p U to objects of
|
||||||
|
/// type \p T
|
||||||
|
///
|
||||||
|
/// \param obj object whose value to replace
|
||||||
|
/// \param new_value the value to assign to obj
|
||||||
|
template <typename T, typename U = T>
|
||||||
|
BPSTD_CPP14_CONSTEXPR T exchange(T& obj, U&& new_value);
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// class : pair
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
using pair = std::pair<T,U>;
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// non-member functions : class : pair
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Utilities
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// C++11 does not implement const pair&&
|
||||||
|
template <std::size_t N, typename T, typename U>
|
||||||
|
constexpr conditional_t<N==0,T,U>& get(pair<T, U>& p) noexcept;
|
||||||
|
template <std::size_t N, typename T, typename U>
|
||||||
|
constexpr conditional_t<N==0,T,U>&& get(pair<T, U>&& p) noexcept;
|
||||||
|
template <std::size_t N, typename T, typename U>
|
||||||
|
constexpr const conditional_t<N==0,T,U>& get(const pair<T, U>& p) noexcept;
|
||||||
|
template <std::size_t N, typename T, typename U>
|
||||||
|
constexpr const conditional_t<N==0,T,U>&& get(const pair<T, U>&& p) noexcept;
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
constexpr T& get(pair<T, U>& p) noexcept;
|
||||||
|
template <typename T, typename U>
|
||||||
|
constexpr T&& get(pair<T, U>&& p) noexcept;
|
||||||
|
template <typename T, typename U>
|
||||||
|
constexpr const T& get(const pair<T, U>& p) noexcept;
|
||||||
|
template <typename T, typename U>
|
||||||
|
constexpr const T&& get(const pair<T, U>&& p) noexcept;
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
constexpr T& get(pair<U, T>& p) noexcept;
|
||||||
|
template <typename T, typename U>
|
||||||
|
constexpr const T& get(const pair<U, T>& p) noexcept;
|
||||||
|
template <typename T, typename U>
|
||||||
|
constexpr T&& get(pair<U, T>&& p) noexcept;
|
||||||
|
template <typename T, typename U>
|
||||||
|
constexpr const T&& get(const pair<U, T>&& p) noexcept;
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// struct : integer_sequence
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
template <typename T, T... Ints>
|
||||||
|
struct integer_sequence
|
||||||
|
{
|
||||||
|
using value_type = T;
|
||||||
|
|
||||||
|
static constexpr std::size_t size() noexcept { return sizeof...(Ints); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <std::size_t... Ints>
|
||||||
|
using index_sequence = integer_sequence<std::size_t, Ints...>;
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
template <typename T, bool End, T N, T...Tails>
|
||||||
|
struct make_integer_sequence_impl
|
||||||
|
: make_integer_sequence_impl<T,((N-1) == T(0)), N-1, N-1, Tails...>{};
|
||||||
|
|
||||||
|
template <typename T, T N, T...Tails>
|
||||||
|
struct make_integer_sequence_impl<T, true, N, Tails...>
|
||||||
|
: type_identity<integer_sequence<T, Tails...>>{};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template <typename T, T N>
|
||||||
|
using make_integer_sequence
|
||||||
|
= typename detail::make_integer_sequence_impl<T, (N==T(0)), N>::type;
|
||||||
|
|
||||||
|
template<std::size_t N>
|
||||||
|
using make_index_sequence = make_integer_sequence<std::size_t, N>;
|
||||||
|
|
||||||
|
template<typename... T>
|
||||||
|
using index_sequence_for = make_index_sequence<sizeof...(T)>;
|
||||||
|
|
||||||
|
} // namespace bpstd
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
// non-member functions
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Utilities
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
typename bpstd::conditional<
|
||||||
|
!bpstd::is_nothrow_move_constructible<T>::value && bpstd::is_copy_constructible<T>::value,
|
||||||
|
const T&,
|
||||||
|
T&&
|
||||||
|
>::type bpstd::move_if_noexcept(T& x)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
using result_type = conditional_t<
|
||||||
|
!is_nothrow_move_constructible<T>::value && is_copy_constructible<T>::value,
|
||||||
|
const T&,
|
||||||
|
T&&
|
||||||
|
>;
|
||||||
|
|
||||||
|
return static_cast<result_type>(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::add_const_t<T>& bpstd::as_const(T& t)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
|
||||||
|
T bpstd::exchange(T& obj, U&& new_value)
|
||||||
|
{
|
||||||
|
auto old_value = bpstd::move(obj);
|
||||||
|
obj = bpstd::forward<U>(new_value);
|
||||||
|
return old_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
// definitions : non-member functions : class : pair
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Utilities
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <std::size_t N, typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::conditional_t<N==0,T,U>&
|
||||||
|
bpstd::get(pair<T, U>& p)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
static_assert(N<=1, "N must be either 0 or 1 for get<N>(pair<T,U>)");
|
||||||
|
|
||||||
|
return std::get<N>(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t N, typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
bpstd::conditional_t<N==0,T,U>&&
|
||||||
|
bpstd::get(pair<T, U>&& p)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
static_assert(N<=1, "N must be either 0 or 1 for get<N>(pair<T,U>)");
|
||||||
|
|
||||||
|
return move(std::get<N>(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t N, typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
const bpstd::conditional_t<N==0,T,U>&
|
||||||
|
bpstd::get(const pair<T, U>& p)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
static_assert(N<=1, "N must be either 0 or 1 for get<N>(pair<T,U>)");
|
||||||
|
|
||||||
|
return std::get<N>(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t N, typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
const bpstd::conditional_t<N==0,T,U>&&
|
||||||
|
bpstd::get(const pair<T, U>&& p)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
static_assert(N<=1, "N must be either 0 or 1 for get<N>(pair<T,U>)");
|
||||||
|
|
||||||
|
return move(std::get<N>(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
T& bpstd::get(pair<T, U>& p)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return p.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
const T& bpstd::get(const pair<T, U>& p)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return p.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
T&& bpstd::get(pair<T, U>&& p)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return move(p.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
const T&& bpstd::get(const pair<T, U>&& p)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return move(p.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
T& bpstd::get(pair<U, T>& p)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return p.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
const T& bpstd::get(const pair<U, T>& p)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return p.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
T&& bpstd::get(pair<U, T>&& p)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return move(p.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
inline BPSTD_INLINE_VISIBILITY constexpr
|
||||||
|
const T&& bpstd::get(const pair<U, T>&& p)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return move(p.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE
|
||||||
|
|
||||||
|
#endif /* BPSTD_UTILITY_HPP */
|
1956
src/libs/vmisc/bpstd/variant.hpp
Normal file
1956
src/libs/vmisc/bpstd/variant.hpp
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -26,6 +26,33 @@ contains(DEFINES, APPIMAGE) {
|
||||||
}
|
}
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
|
$$PWD/bpstd/any.hpp \
|
||||||
|
$$PWD/bpstd/chrono.hpp \
|
||||||
|
$$PWD/bpstd/complex.hpp \
|
||||||
|
$$PWD/bpstd/cstddef.hpp \
|
||||||
|
$$PWD/bpstd/detail/config.hpp \
|
||||||
|
$$PWD/bpstd/detail/enable_overload.hpp \
|
||||||
|
$$PWD/bpstd/detail/invoke.hpp \
|
||||||
|
$$PWD/bpstd/detail/move.hpp \
|
||||||
|
$$PWD/bpstd/detail/nth_type.hpp \
|
||||||
|
$$PWD/bpstd/detail/proxy_iterator.hpp \
|
||||||
|
$$PWD/bpstd/detail/variant_base.hpp \
|
||||||
|
$$PWD/bpstd/detail/variant_fwds.hpp \
|
||||||
|
$$PWD/bpstd/detail/variant_traits.hpp \
|
||||||
|
$$PWD/bpstd/detail/variant_union.hpp \
|
||||||
|
$$PWD/bpstd/detail/variant_visitors.hpp \
|
||||||
|
$$PWD/bpstd/exception.hpp \
|
||||||
|
$$PWD/bpstd/functional.hpp \
|
||||||
|
$$PWD/bpstd/iterator.hpp \
|
||||||
|
$$PWD/bpstd/memory.hpp \
|
||||||
|
$$PWD/bpstd/optional.hpp \
|
||||||
|
$$PWD/bpstd/span.hpp \
|
||||||
|
$$PWD/bpstd/string.hpp \
|
||||||
|
$$PWD/bpstd/string_view.hpp \
|
||||||
|
$$PWD/bpstd/tuple.hpp \
|
||||||
|
$$PWD/bpstd/type_traits.hpp \
|
||||||
|
$$PWD/bpstd/utility.hpp \
|
||||||
|
$$PWD/bpstd/variant.hpp \
|
||||||
$$PWD/compatibility.h \
|
$$PWD/compatibility.h \
|
||||||
$$PWD/lambdaconstants.h \
|
$$PWD/lambdaconstants.h \
|
||||||
$$PWD/stable.h \
|
$$PWD/stable.h \
|
||||||
|
|
Loading…
Reference in New Issue
Block a user