From 4b5d41f2c14d0b75cd9746a2dbeeaf2370aebd12 Mon Sep 17 00:00:00 2001 From: Steve Lhomme Date: Wed, 22 Oct 2025 16:40:14 +0200 Subject: [PATCH] adaptive: use standard even on macOS Using value() potentially throws an exception that is not always available on macOS. Since XCode 16 it's considered available in all macOS, iOS, etc. ``` XCode 16.4+ #define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS _LIBCPP_INTRODUCED_IN_LLVM_4_ATTRIBUTE XCode 12.5-15.4 # define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS \ __attribute__((availability(macos,strict,introduced=10.13))) \ __attribute__((availability(ios,strict,introduced=12.0))) \ __attribute__((availability(tvos,strict,introduced=12.0))) \ __attribute__((availability(watchos,strict,introduced=5.0))) XCode 11-12.2 # define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS \ __attribute__((availability(macosx,strict,introduced=10.14))) \ __attribute__((availability(ios,strict,introduced=12.0))) \ __attribute__((availability(tvos,strict,introduced=12.0))) \ __attribute__((availability(watchos,strict,introduced=5.0))) XCode 9.2 #define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable)) ``` We never use the class directly, nor catch the error. --- modules/demux/Makefile.am | 1 - .../demux/adaptive/http/HTTPConnection.cpp | 7 +- .../demux/adaptive/logic/BufferingLogic.hpp | 4 +- .../adaptive/playlist/BaseAdaptationSet.h | 5 +- .../playlist/CommonAttributesElements.h | 1 - .../demux/adaptive/tools/Compatibility.hpp | 214 ------------------ modules/demux/hls/playlist/Parser.cpp | 4 +- modules/demux/hls/playlist/Tags.cpp | 4 +- modules/demux/hls/playlist/Tags.hpp | 5 +- 9 files changed, 15 insertions(+), 230 deletions(-) delete mode 100644 modules/demux/adaptive/tools/Compatibility.hpp diff --git a/modules/demux/Makefile.am b/modules/demux/Makefile.am index 2e572ec294..c5dee5977b 100644 --- a/modules/demux/Makefile.am +++ b/modules/demux/Makefile.am @@ -407,7 +407,6 @@ libvlc_adaptive_la_SOURCES = \ demux/adaptive/Streams.cpp \ demux/adaptive/Streams.hpp \ demux/adaptive/Time.hpp \ - demux/adaptive/tools/Compatibility.hpp \ demux/adaptive/tools/Conversions.hpp \ demux/adaptive/tools/Conversions.cpp \ demux/adaptive/tools/Debug.hpp \ diff --git a/modules/demux/adaptive/http/HTTPConnection.cpp b/modules/demux/adaptive/http/HTTPConnection.cpp index 980d1ee966..4e86e86d98 100644 --- a/modules/demux/adaptive/http/HTTPConnection.cpp +++ b/modules/demux/adaptive/http/HTTPConnection.cpp @@ -26,7 +26,8 @@ #include "AuthStorage.hpp" #include "../BlockStreamInterface.hpp" #include "../plumbing/SourceStream.hpp" -#include "../tools/Compatibility.hpp" + +#include #include #include @@ -189,8 +190,8 @@ class adaptive::http::LibVLCHTTPSource : public adaptive::BlockStreamInterface struct vlc_http_mgr *http_mgr; BytesRange range; struct vlc_http_resource *http_res; - adaptive::optional username; - adaptive::optional password; + std::optional username; + std::optional password; ConnectionParams lastparams; public: diff --git a/modules/demux/adaptive/logic/BufferingLogic.hpp b/modules/demux/adaptive/logic/BufferingLogic.hpp index eb7991bb5e..2a0a455fa2 100644 --- a/modules/demux/adaptive/logic/BufferingLogic.hpp +++ b/modules/demux/adaptive/logic/BufferingLogic.hpp @@ -23,7 +23,7 @@ #include #include -#include "../tools/Compatibility.hpp" +#include namespace adaptive { @@ -61,7 +61,7 @@ namespace adaptive vlc_tick_t userMinBuffering; vlc_tick_t userMaxBuffering; vlc_tick_t userLiveDelay; - optional userLowLatency; + std::optional userLowLatency; }; class DefaultBufferingLogic : public AbstractBufferingLogic diff --git a/modules/demux/adaptive/playlist/BaseAdaptationSet.h b/modules/demux/adaptive/playlist/BaseAdaptationSet.h index 45ad54d2ab..36c73e2eec 100644 --- a/modules/demux/adaptive/playlist/BaseAdaptationSet.h +++ b/modules/demux/adaptive/playlist/BaseAdaptationSet.h @@ -27,6 +27,7 @@ #include #include +#include #include "CommonAttributesElements.h" #include "SegmentInformation.hpp" @@ -68,8 +69,8 @@ namespace adaptive Role role; std::vector representations; std::string lang; - optional segmentAligned; - optional bitswitchAble; + std::optional segmentAligned; + std::optional bitswitchAble; }; } } diff --git a/modules/demux/adaptive/playlist/CommonAttributesElements.h b/modules/demux/adaptive/playlist/CommonAttributesElements.h index d9d9b9fe08..ab85685ac5 100644 --- a/modules/demux/adaptive/playlist/CommonAttributesElements.h +++ b/modules/demux/adaptive/playlist/CommonAttributesElements.h @@ -24,7 +24,6 @@ #ifndef COMMONATTRIBUTESELEMENTS_H #define COMMONATTRIBUTESELEMENTS_H -#include "../tools/Compatibility.hpp" #include "../tools/Properties.hpp" #include "../tools/Macros.hpp" #include diff --git a/modules/demux/adaptive/tools/Compatibility.hpp b/modules/demux/adaptive/tools/Compatibility.hpp deleted file mode 100644 index d97eaedda3..0000000000 --- a/modules/demux/adaptive/tools/Compatibility.hpp +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Compatibility.hpp - ***************************************************************************** - * Copyright (C) 2025 - VideoLabs, VideoLAN and VLC Authors - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. - *****************************************************************************/ -#ifndef COMPATIBILITY_HPP -#define COMPATIBILITY_HPP - -/* Provide std::optional compatibility for builds with c++17 or - incomplete/bogus c++17 with MacOS <= 10.13 and iOS < 12 */ - -#ifdef __APPLE__ -# include -# if (TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED < 120000) || \ - (TARGET_OS_MAC && __MAC_OS_X_VERSION_MIN_REQUIRED < 101400) -# define IOS_INCOMPLETE_CPP17 -# endif -#endif - -#if __cplusplus >= 201703L && !defined(IOS_INCOMPLETE_CPP17) -# include -#else -# include -# include -# include -#endif - -namespace adaptive -{ - -#if __cplusplus >= 201703L && !defined(IOS_INCOMPLETE_CPP17) - -template -using optional = std::optional; -using nullopt_t = std::nullopt_t; -constexpr auto nullopt = std::nullopt; -using in_place_t = std::in_place_t; -constexpr auto in_place = std::in_place; -using bad_optional_access = std::bad_optional_access; -#else - -struct nullopt_t { - explicit nullopt_t() = default; -}; -constexpr nullopt_t nullopt{}; - -struct in_place_t { - explicit in_place_t() = default; -}; -constexpr in_place_t in_place{}; - -class bad_optional_access : public std::exception { -public: - const char* what() const noexcept override { - return "Bad optional access"; - } -}; - -template -class optional -{ -private: - alignas(T) unsigned char storage[sizeof(T)]; - bool has_value_ = false; - - T* ptr() noexcept - { - return reinterpret_cast(storage); - } - const T* ptr() const noexcept - { - return reinterpret_cast(storage); - } - - void destroy() noexcept(std::is_nothrow_destructible::value) - { - if (has_value_) - { - ptr()->~T(); - has_value_ = false; - } - } - -public: - optional() noexcept = default; - - optional(nullopt_t) noexcept : optional() {} - - optional(const T& value) : has_value_(true) - { - new (storage) T(value); - } - optional(T&& value) : has_value_(true) - { - new (storage) T(std::move(value)); - } - optional(optional&& other) noexcept(std::is_nothrow_move_constructible::value) - : has_value_(other.has_value_) { - if (has_value_) { new (storage) T(std::move(*other.ptr())); other.destroy(); } - } - - ~optional() {destroy();} - - optional& operator=(const optional& other) - { - if (this != &other) - { - destroy(); - has_value_ = other.has_value_; - if (has_value_) - new (storage) T(*other.ptr()); - } - return *this; - } - - optional& operator=(optional&& other) noexcept( - std::is_nothrow_move_constructible::value && - std::is_nothrow_move_assignable::value) - { - if (this != &other) - { - destroy(); - has_value_ = other.has_value_; - if (has_value_) - { - new (storage) T(std::move(*other.ptr())); - other.destroy(); - } - } - return *this; - } - - optional& operator=(nullopt_t) noexcept - { - destroy(); - return *this; - } - - optional& operator=(const T& value) - { - destroy(); - has_value_ = true; - new (storage) T(value); - return *this; - } - optional& operator=(T&& value) - { - destroy(); - has_value_ = true; - new (storage) T(std::move(value)); - return *this; - } - - template - void emplace(Args&&... args) - { - destroy(); - has_value_ = true; - new (storage) T(std::forward(args)...); - } - - explicit operator bool() const noexcept { return has_value_; } - bool has_value() const noexcept { return has_value_; } - - T& value() - { - if (!has_value_) throw bad_optional_access{}; - return *ptr(); - } - const T& value() const - { - if (!has_value_) throw bad_optional_access{}; - return *ptr(); - } - - T* operator->() { return ptr(); } - const T* operator->() const { return ptr(); } - T& operator*() { return *ptr(); } - const T& operator*() const { return *ptr(); } - - template - T value_or(U&& default_value) const& { - return has_value_ ? *ptr() : static_cast(std::forward(default_value)); - } - template - T value_or(U&& default_value) && { - return has_value_ ? std::move(*ptr()) : static_cast(std::forward(default_value)); - } - - void reset() noexcept - { - destroy(); - } -}; - -#endif // #if __cplusplus < 201703L - -} - -#endif // COMPATIBILITY_HPP diff --git a/modules/demux/hls/playlist/Parser.cpp b/modules/demux/hls/playlist/Parser.cpp index 363c931dee..312b41e795 100644 --- a/modules/demux/hls/playlist/Parser.cpp +++ b/modules/demux/hls/playlist/Parser.cpp @@ -365,8 +365,8 @@ void M3U8Parser::parseSegments(vlc_object_t *, HLSRepresentation *rep, const std ByteRange range = ctx_byterange->getValue().getByteRange(); if(!range.first.has_value()) /* first == offset, second = length */ range.first = prevbyterangeoffset; - prevbyterangeoffset = range.first.value() + range.second; - segment->setByteRange(range.first.value(), prevbyterangeoffset - 1); + prevbyterangeoffset = *range.first + range.second; + segment->setByteRange(*range.first, prevbyterangeoffset - 1); ctx_byterange = nullptr; } segment->setDiscontinuitySequenceNumber(discontinuitySequence); diff --git a/modules/demux/hls/playlist/Tags.cpp b/modules/demux/hls/playlist/Tags.cpp index 8f9fdb8404..d407c53581 100644 --- a/modules/demux/hls/playlist/Tags.cpp +++ b/modules/demux/hls/playlist/Tags.cpp @@ -70,7 +70,7 @@ std::vector Attribute::hexSequence() const return ret; } -static inline std::istream& operator>>(std::istream& is, adaptive::optional& data) +static inline std::istream& operator>>(std::istream& is, std::optional& data) { size_t val; if(is >> val) @@ -81,7 +81,7 @@ static inline std::istream& operator>>(std::istream& is, adaptive::optional offset; + std::optional offset; std::istringstream is(value); is.imbue(std::locale("C")); diff --git a/modules/demux/hls/playlist/Tags.hpp b/modules/demux/hls/playlist/Tags.hpp index 282baef85b..fa00903dfe 100644 --- a/modules/demux/hls/playlist/Tags.hpp +++ b/modules/demux/hls/playlist/Tags.hpp @@ -20,21 +20,20 @@ #ifndef TAGS_HPP #define TAGS_HPP -#include "../../adaptive/tools/Compatibility.hpp" - #include #include #include #include #include +#include namespace hls { namespace playlist { - using ByteRange = std::pair,std::size_t>; + using ByteRange = std::pair,std::size_t>; class Attribute {