diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e6551144..5b51941b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -116,6 +116,10 @@ jobs: run: 'echo "${{ runner.workspace }}/b/ninja/src" >> $GITHUB_PATH' shell: bash + - name: Show library sizes + run: 'ls -l "${{ runner.workspace }}/b/ninja/src"' + shell: bash + - name: 'Run tests' run: ctest . --output-on-failure working-directory: '${{ runner.workspace }}/b/ninja' diff --git a/include/adm/detail/auto_base.hpp b/include/adm/detail/auto_base.hpp index d8d07262..e3f66d46 100644 --- a/include/adm/detail/auto_base.hpp +++ b/include/adm/detail/auto_base.hpp @@ -1,5 +1,6 @@ #pragma once #include "adm/detail/auto_base_detail.hpp" +#include "adm/detail/holds_alternative.hpp" #include "adm/detail/type_traits.hpp" #include "adm/export.h" #include "boost/optional.hpp" @@ -296,12 +297,13 @@ namespace adm { using VariantParam::has; ADM_BASE_EXPORT bool has(Tag) const { - return has(VariantTag{}) && get(VariantTag()).type() == typeid(T); + return has(VariantTag{}) && holds_alternative(get(VariantTag())); } using VariantParam::isDefault; ADM_BASE_EXPORT bool isDefault(Tag) const { - return isDefault(VariantTag()) && get(VariantTag()).type() == typeid(T); + return isDefault(VariantTag()) && + holds_alternative(get(VariantTag())); } using VariantParam::unset; diff --git a/include/adm/detail/holds_alternative.hpp b/include/adm/detail/holds_alternative.hpp new file mode 100644 index 00000000..d24ecd26 --- /dev/null +++ b/include/adm/detail/holds_alternative.hpp @@ -0,0 +1,61 @@ +#pragma once + +#include + +namespace adm { + namespace detail { + + /// implementation of variant_type_index; finds the index of type T within + /// variant V, or -1 if it's not found + template + struct VariantTypeIndexImpl; + + // base case when T is found at index i + template + struct VariantTypeIndexImpl { + static constexpr int index = i; + }; + + // recursive case where T is not at index i + template + struct VariantTypeIndexImpl { + static constexpr int index = VariantTypeIndexImpl::index; + }; + + // base case at end of list, to get a nice error + template + struct VariantTypeIndexImpl { + static constexpr int index = -1; + }; + + template + struct VariantTypeIndexWrapper; + + template + struct VariantTypeIndexWrapper> { + static constexpr int index = VariantTypeIndexImpl<0, T, Vt...>::index; + }; + + /// get the index of a type T within Variant + /// + /// for example, variant_type_index>() == 0 + /// + /// static_asserts if the type is not found + template + constexpr int variant_type_index() { + constexpr int index = VariantTypeIndexWrapper::index; + static_assert(index != -1, "variant cannot hold the given type"); + + return index; + } + + /// check if a variant holds a given type + /// + /// for example, holds_alternative(boost::variant(1)) == true + template + constexpr bool holds_alternative(const Variant &v) { + return v.which() == variant_type_index(); + } + + } // namespace detail +} // namespace adm diff --git a/include/adm/element_variant.hpp b/include/adm/element_variant.hpp index 3de95bb7..b1aebd1e 100644 --- a/include/adm/element_variant.hpp +++ b/include/adm/element_variant.hpp @@ -1,5 +1,6 @@ #pragma once +#include "adm/detail/holds_alternative.hpp" #include "adm/elements.hpp" #include #include @@ -26,13 +27,13 @@ namespace adm { template struct IsVariantType { bool operator()(const Variant& v) const { - return v.type() == typeid(VariantType); + return detail::holds_alternative(v); } }; template bool isVariantType(const Variant& v) { - return v.type() == typeid(VariantType); + return detail::holds_alternative(v); } template diff --git a/include/adm/elements/time.hpp b/include/adm/elements/time.hpp index 65116ecb..43d7193f 100644 --- a/include/adm/elements/time.hpp +++ b/include/adm/elements/time.hpp @@ -6,6 +6,7 @@ #include #include #include "adm/detail/named_type.hpp" +#include "adm/detail/holds_alternative.hpp" #include "adm/export.h" namespace adm { @@ -58,9 +59,11 @@ namespace adm { ADM_EXPORT FractionalTime asFractional() const; bool isNanoseconds() const { - return time.type() == typeid(std::chrono::nanoseconds); + return detail::holds_alternative(time); + } + bool isFractional() const { + return detail::holds_alternative(time); } - bool isFractional() const { return time.type() == typeid(FractionalTime); }; using Variant = boost::variant; const Variant& asVariant() const { return time; } diff --git a/src/elements/audio_block_format_objects.cpp b/src/elements/audio_block_format_objects.cpp index cb82f474..78e60171 100644 --- a/src/elements/audio_block_format_objects.cpp +++ b/src/elements/audio_block_format_objects.cpp @@ -130,11 +130,8 @@ namespace adm { } } void AudioBlockFormatObjects::set(Position position) { - if (position.which() == 0) { - set(boost::get(position)); - } else if (position.which() == 1) { - set(boost::get(position)); - } + boost::apply_visitor([this](auto p) { set(std::move(p)); }, + std::move(position)); } void AudioBlockFormatObjects::set(SphericalPosition position) { sphericalPosition_ = position; diff --git a/src/elements/audio_content.cpp b/src/elements/audio_content.cpp index a26b5f59..e863e896 100644 --- a/src/elements/audio_content.cpp +++ b/src/elements/audio_content.cpp @@ -110,13 +110,7 @@ namespace adm { } } void AudioContent::set(ContentKind kind) { - if (kind.which() == 0) { - set(boost::get(kind)); - } else if (kind.which() == 1) { - set(boost::get(kind)); - } else if (kind.which() == 2) { - set(boost::get(kind)); - } + boost::apply_visitor([this](auto k) { set(k); }, kind); } void AudioContent::set(NonDialogueContentKind kind) { unset(); diff --git a/src/elements/position.cpp b/src/elements/position.cpp index 5f3632e1..0efd9c45 100644 --- a/src/elements/position.cpp +++ b/src/elements/position.cpp @@ -1,3 +1,4 @@ +#include "adm/detail/holds_alternative.hpp" #include "adm/elements/position.hpp" namespace adm { @@ -123,19 +124,11 @@ namespace adm { // ---- FREE FUNCTIONS ---- // bool isSpherical(const Position& position) { - if (position.which() == 0) { - return true; - } else { - return false; - } + return detail::holds_alternative(position); } bool isCartesian(const Position& position) { - if (position.which() == 1) { - return true; - } else { - return false; - } + return detail::holds_alternative(position); } } // namespace adm diff --git a/src/elements/position_offset.cpp b/src/elements/position_offset.cpp index 6051a7e9..3e1756d6 100644 --- a/src/elements/position_offset.cpp +++ b/src/elements/position_offset.cpp @@ -1,4 +1,5 @@ #include "adm/elements/position_offset.hpp" +#include "adm/detail/holds_alternative.hpp" #include "adm/detail/print_helper.hpp" namespace adm { @@ -30,11 +31,11 @@ namespace adm { } bool isSpherical(const PositionOffset& offset) { - return offset.type() == typeid(SphericalPositionOffset); + return detail::holds_alternative(offset); } bool isCartesian(const PositionOffset& offset) { - return offset.type() == typeid(CartesianPositionOffset); + return detail::holds_alternative(offset); } } // namespace adm