[vlc-commits] [Git][videolan/vlc][master] adaptive: use standard <optional> even on macOS

Steve Lhomme (@robUx4) gitlab at videolan.org
Sun Oct 26 08:46:20 UTC 2025



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
4b5d41f2 by Steve Lhomme at 2025-10-26T08:31:52+00:00
adaptive: use standard <optional> 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.

- - - - -


9 changed files:

- modules/demux/Makefile.am
- modules/demux/adaptive/http/HTTPConnection.cpp
- modules/demux/adaptive/logic/BufferingLogic.hpp
- modules/demux/adaptive/playlist/BaseAdaptationSet.h
- modules/demux/adaptive/playlist/CommonAttributesElements.h
- − modules/demux/adaptive/tools/Compatibility.hpp
- modules/demux/hls/playlist/Parser.cpp
- modules/demux/hls/playlist/Tags.cpp
- modules/demux/hls/playlist/Tags.hpp


Changes:

=====================================
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 \


=====================================
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 <optional>
 
 #include <vlc_stream.h>
 #include <vlc_keystore.h>
@@ -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<std::string> username;
-        adaptive::optional<std::string> password;
+        std::optional<std::string> username;
+        std::optional<std::string> password;
         ConnectionParams lastparams;
 
     public:


=====================================
modules/demux/adaptive/logic/BufferingLogic.hpp
=====================================
@@ -23,7 +23,7 @@
 #include <vlc_common.h>
 #include <vlc_tick.h>
 
-#include "../tools/Compatibility.hpp"
+#include <optional>
 
 namespace adaptive
 {
@@ -61,7 +61,7 @@ namespace adaptive
                 vlc_tick_t userMinBuffering;
                 vlc_tick_t userMaxBuffering;
                 vlc_tick_t userLiveDelay;
-                optional<bool> userLowLatency;
+                std::optional<bool> userLowLatency;
         };
 
         class DefaultBufferingLogic : public AbstractBufferingLogic


=====================================
modules/demux/adaptive/playlist/BaseAdaptationSet.h
=====================================
@@ -27,6 +27,7 @@
 
 #include <vector>
 #include <string>
+#include <optional>
 
 #include "CommonAttributesElements.h"
 #include "SegmentInformation.hpp"
@@ -68,8 +69,8 @@ namespace adaptive
                 Role                            role;
                 std::vector<BaseRepresentation *>   representations;
                 std::string                     lang;
-                optional<bool>                  segmentAligned;
-                optional<bool>                  bitswitchAble;
+                std::optional<bool>             segmentAligned;
+                std::optional<bool>             bitswitchAble;
         };
     }
 }


=====================================
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 <string>


=====================================
modules/demux/adaptive/tools/Compatibility.hpp deleted
=====================================
@@ -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 <TargetConditionals.h>
-# 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 <optional>
-#else
-# include <utility>
-# include <type_traits>
-# include <stdexcept>
-#endif
-
-namespace adaptive
-{
-
-#if __cplusplus >= 201703L && !defined(IOS_INCOMPLETE_CPP17)
-
-template <typename T>
-using optional = std::optional<T>;
-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 <typename T>
-class optional
-{
-private:
-    alignas(T) unsigned char storage[sizeof(T)];
-    bool has_value_ = false;
-
-    T* ptr() noexcept
-    {
-        return reinterpret_cast<T*>(storage);
-    }
-    const T* ptr() const noexcept
-    {
-        return reinterpret_cast<const T*>(storage);
-    }
-
-    void destroy() noexcept(std::is_nothrow_destructible<T>::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<T>::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<T>::value &&
-        std::is_nothrow_move_assignable<T>::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 <typename... Args>
-    void emplace(Args&&... args)
-    {
-        destroy();
-        has_value_ = true;
-        new (storage) T(std::forward<Args>(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 <typename U>
-    T value_or(U&& default_value) const& {
-        return has_value_ ? *ptr() : static_cast<T>(std::forward<U>(default_value));
-    }
-    template <typename U>
-    T value_or(U&& default_value) && {
-        return has_value_ ? std::move(*ptr()) : static_cast<T>(std::forward<U>(default_value));
-    }
-
-    void reset() noexcept
-    {
-        destroy();
-    }
-};
-
-#endif // #if __cplusplus < 201703L
-
-}
-
-#endif // COMPATIBILITY_HPP


=====================================
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);


=====================================
modules/demux/hls/playlist/Tags.cpp
=====================================
@@ -70,7 +70,7 @@ std::vector<uint8_t> Attribute::hexSequence() const
     return ret;
 }
 
-static inline std::istream& operator>>(std::istream& is, adaptive::optional<std::size_t>& data)
+static inline std::istream& operator>>(std::istream& is, std::optional<std::size_t>& data)
 {
     size_t val;
     if(is >> val)
@@ -81,7 +81,7 @@ static inline std::istream& operator>>(std::istream& is, adaptive::optional<std:
 ByteRange Attribute::getByteRange() const
 {
     std::size_t length;
-    adaptive::optional<std::size_t> offset;
+    std::optional<std::size_t> offset;
     std::istringstream is(value);
     is.imbue(std::locale("C"));
 


=====================================
modules/demux/hls/playlist/Tags.hpp
=====================================
@@ -20,21 +20,20 @@
 #ifndef TAGS_HPP
 #define TAGS_HPP
 
-#include "../../adaptive/tools/Compatibility.hpp"
-
 #include <stdint.h>
 
 #include <string>
 #include <vector>
 #include <list>
 #include <utility>
+#include <optional>
 
 namespace hls
 {
 
     namespace playlist
     {
-        using ByteRange = std::pair<adaptive::optional<std::size_t>,std::size_t>;
+        using ByteRange = std::pair<std::optional<std::size_t>,std::size_t>;
 
         class Attribute
         {



View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/4b5d41f2c14d0b75cd9746a2dbeeaf2370aebd12

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/4b5d41f2c14d0b75cd9746a2dbeeaf2370aebd12
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list