**File:** modules/core/include/opencv2/core/cuda.hpp
**Change Type:** modified
**Context:** PR #19286: add cuda::Stream constructor with cuda stream flags

**Code Changes:**
```diff
@@ -656,6 +656,18 @@ class CV_EXPORTS_W Stream
     //! creates a new asynchronous stream with custom allocator
     CV_WRAP Stream(const Ptr<GpuMat::Allocator>& allocator);
 
+    /** @brief creates a new Stream using the cudaFlags argument to determine the behaviors of the stream
+
+    @note The cudaFlags parameter is passed to the underlying api cudaStreamCreateWithFlags() and
+    supports the same parameter values.
+    @code
+        // creates an OpenCV cuda::Stream that manages an asynchronous, non-blocking,
```

Review comment:
The ask is a constructor for the reasons that I wrote in the original issue https://github.com/opencv/opencv/issues/19285. Please reference there for details including the unusable existing function `cv::cuda::StreamAccessor::wrapStream()`. A constructor can provide the instantiated object itself or a pointer to an instantiated object. They are not the same. A pointer is raw and unsafe to use without further wrapping it with unique_ptr or shared_ptr. The object itself is scoped, RAII, etc. Technically both are valid. But only a constructor can create an object itself into an lvalue. ```c++ // safe, destructs when out of scope cv::cuda::Stream stream_obj(std::move((void *)my_cudaStream_t)); // dangerous raw pointer, does not destruct itself, often multiple memory bugs by app programmers cv::cuda::Stream* stream_ptr = cv::cuda::Stream::fromCudaStream(std::move((void *)my_cudaStream_t)); // safer, valid, more work std::unique_ptr<cv::cuda::Stream> stream_ptr(cv::cuda::Stream::fromCudaStream(std::move((void *)my_cudaStream_t))); // safe, simple, and requires a constructor struct threadTLSData{ cv::cuda::Stream cvStream; int otherThings; }; return { cv::cuda::Stream(std::move((void *)_stream)), 42 }; // without a constructor have to wrap it all and requires C++11 compiler correctly supports copy elision struct threadTLSData{ std::unique_ptr<cv::cuda::Stream> cvStream; // share_ptr isn't as strict with elision, but has more overhead when we don't need it here int otherThings; }; return { // also can not use std::make_unique or std::make_shared because they both require a constructor // also make_unique is only in C++14 and newer yet OpenCV wants to target C++11 // this direct unique_ptr constructor method is often unsafe in C++11 due to parameter evaluation order // with exceptions. For safety, need make_unique in C++14 -or- use C++17 standard that fixed this // https://www.learncpp.com/cpp-tutorial/stdunique_ptr/#urvanov-syntax-highlighter-600141f5f0789724071531 std::unique_ptr<cv::cuda::Stream>(cv::cuda::Stream::fromCudaStream(std::move((void *)my_cudaStream_t))), 42 }; ``` OpenCV is often not strong type checked. As I discuss in the issue #19285, this is a development choice by the core team. They did not want to include headers (e.g. CUDA, OpenCL) and fix issues at compile time, so they wrote generic parameters/returns like `void*` and throw asserts at runtime. For example: `cv::ocl::Device(void*)`, `void* cv::cuda::Stream::cudaPtr()`, `cv::cuda::Stream::Stream()` that throws, or the whole auxiliary namespace `cv::cuda::StreamAccessor`. I would have taken a different approach with strong type safety and fix at compile time. However since the core team choose the generic `void*` and assert approach, I suggest we continue that approach for consistency plus the above benefits of having a constructor. I've coded it like that in the PR. ### Options #### Constructor with `Stream::Stream(void*&& cudaStream)` See original post and PR #### Static factory `static Stream::fromCudaStream(void*&& cudaStream)` I can write a lesser feature with a static factory like `static cv::cuda::Stream::fromCudaStream(void*&& cudaStream)`. It will have the limitations and more difficult usage that I describe above in words and pseudocode. #### Use type-safety Make a breaking change to the `cv::cuda` module to end the use of `void*` on public APIs. This requires the inclusion some cuda headers so that types like `cudaStream_t` can be used in APIs like this new constructor, existing `Stream::cudaPtr()`, etc. #### Gated availability of type-safe constructor It should be easy to use `#ifdef HAVE_CUDA` to test for availability of CUDA, optionally include CUDA headers and declare a type-safe constructor. This would give us a constructor, type-safe, and not required CUDA headers to be loaded unless OpenCV is being built with cuda. For example pseudocode ``` #ifdef HAVE_CUDA #include<cuda.h> cv::cuda::Stream::Stream(cudaStream_t&& cudaStream); #endif ```