nareshmlx/opencv-pr huggingface dataset:
**File:** modules/gapi/src/executor/gtbbexecutor.cpp
**Change Type:** added
**Context:** PR #17851: Sole tbb executor
**Review Line:** 287

**Code Changes:**
```diff
+    //
+    struct task_body {
+        exec_ctx& ctx;
+
+        std::size_t push_ready_dependants(tile_node* node) const {
+            return graph::push_ready_dependants(ctx.q, node);
+        }
+
+        void spawn_clones(std::size_t items) const {
+            tasking::batch_spawn(items, ctx.root.get(), *this);
+        }
```

Review comment:
Is there a reason to take this function out of the `task_body`? I can't find any other usages of it but the ones inside of this class
**File:** modules/gapi/src/executor/gtbbexecutor.cpp
**Change Type:** added
**Context:** PR #17851: Sole tbb executor

**Code Changes:**
```diff
@@ -0,0 +1,445 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+//
+// Copyright (C) 2020 Intel Corporation
+
+#include "gtbbexecutor.hpp"
+
+#if defined(HAVE_TBB)
```

Review comment:
M b it is reasonable to use this before `timer` is declared
**File:** modules/gapi/test/executor/gtbbexecutor_internal_tests.cpp
**Change Type:** added
**Context:** PR #17851: Sole tbb executor
**Review Line:** 126

**Code Changes:**
```diff
+    using namespace cv::gimpl::parallel;
+    const int n = 10;
+    bool serial = true;
+    std::atomic<int> counter {0};
+    prio_items_queue_t q;
+    std::vector<tile_node> nodes; nodes.reserve(n+1);
+    const int invalid_order = -10;
+    std::vector<int> tiles_exec_order(n, invalid_order);
+
+    auto add_dependency_to = [](tile_node& node, tile_node& dependency) {
+        dependency.dependants.push_back(&node);
```

Review comment:
Would you mind to add spaces here, too (`n+1`)
**File:** modules/gapi/test/executor/gtbbexecutor_internal_tests.cpp
**Change Type:** added
**Context:** PR #17851: Sole tbb executor
**Review Line:** 135

**Code Changes:**
```diff
+    auto add_dependency_to = [](tile_node& node, tile_node& dependency) {
+        dependency.dependants.push_back(&node);
+        node.dependencies++;
+        node.dependency_count.fetch_add(1);
+    };
+    for (int i=0; i <n; i++) {
+        nodes.push_back(tile_node([&, i]() {
+                tiles_exec_order[i] = counter++;
+                if (!serial) {
+                    //sleep gives a better chance for other threads to take part in the execution
+                    std::this_thread::sleep_for(std::chrono::milliseconds(10));
```

Review comment:
And spaces here as well
**File:** modules/gapi/test/executor/gtbbexecutor_internal_tests.cpp
**Change Type:** added
**Context:** PR #17851: Sole tbb executor

**Code Changes:**
```diff
@@ -0,0 +1,172 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+//
+// Copyright (C) 2020 Intel Corporation
+
+// Deliberately include .cpp file instead of header as we use non exported function (execute)
+#include <executor/gtbbexecutor.cpp>
+
```

Review comment:
Spaces around `<<`
**File:** modules/gapi/test/executor/gtbbexecutor_internal_tests.cpp
**Change Type:** added
**Context:** PR #17851: Sole tbb executor

**Code Changes:**
```diff
@@ -0,0 +1,172 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+//
+// Copyright (C) 2020 Intel Corporation
+
+// Deliberately include .cpp file instead of header as we use non exported function (execute)
+#include <executor/gtbbexecutor.cpp>
+
```

Review comment:
A space after one of `<<`
**File:** modules/gapi/include/opencv2/gapi/util/copy_through_move.hpp
**Change Type:** added
**Context:** PR #17851: Sole tbb executor
**Review Line:** 21

**Code Changes:**
```diff
+    //This is a tool to move initialize captures of a lambda in C++11
+    template<typename T>
+    struct copy_through_move_t{
+       T value;
+       const T& get() const {return value;}
+       T&       get()       {return value;}
+       copy_through_move_t(T&& g) : value(std::move(g)) {}
+       copy_through_move_t(copy_through_move_t&&) = default;
+       copy_through_move_t(copy_through_move_t const& lhs) : copy_through_move_t(std::move(const_cast<copy_through_move_t&>(lhs))) {}
+    };
+
```

Review comment:
> Or it's non-const because value can be modified, not by the method, but after returning it outside? Correct. `const` one overload to use `const &` to the stored value to forbid it modification
**File:** modules/gapi/test/executor/gtbbexecutor_internal_tests.cpp
**Change Type:** added
**Context:** PR #17851: Sole tbb executor
**Review Line:** 126

**Code Changes:**
```diff
+    using namespace cv::gimpl::parallel;
+    const int n = 10;
+    bool serial = true;
+    std::atomic<int> counter {0};
+    prio_items_queue_t q;
+    std::vector<tile_node> nodes; nodes.reserve(n+1);
+    const int invalid_order = -10;
+    std::vector<int> tiles_exec_order(n, invalid_order);
+
+    auto add_dependency_to = [](tile_node& node, tile_node& dependency) {
+        dependency.dependants.push_back(&node);
```

Review comment:
Sorry, seems like you overlooked. Please, check one more time
**File:** modules/gapi/test/executor/gtbbexecutor_internal_tests.cpp
**Change Type:** added
**Context:** PR #17851: Sole tbb executor
**Review Line:** 126

**Code Changes:**
```diff
+    using namespace cv::gimpl::parallel;
+    const int n = 10;
+    bool serial = true;
+    std::atomic<int> counter {0};
+    prio_items_queue_t q;
+    std::vector<tile_node> nodes; nodes.reserve(n+1);
+    const int invalid_order = -10;
+    std::vector<int> tiles_exec_order(n, invalid_order);
+
+    auto add_dependency_to = [](tile_node& node, tile_node& dependency) {
+        dependency.dependants.push_back(&node);
```

Review comment:
yes, I have left it as is. And here is why: according to [OpenCV coding style](https://github.com/opencv/opencv/wiki/Coding_Style_Guide) - There is a single coding guideline in OpenCV: each single file must use a consistent formatting style. - space after opening bracket `(` and before closing bracket `)` are not recommended So I made it consistent (at least tried to)
**File:** modules/gapi/test/executor/gtbbexecutor_internal_tests.cpp
**Change Type:** added
**Context:** PR #17851: Sole tbb executor

**Code Changes:**
```diff
@@ -0,0 +1,172 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+//
+// Copyright (C) 2020 Intel Corporation
+
+// Deliberately include .cpp file instead of header as we use non exported function (execute)
+#include <executor/gtbbexecutor.cpp>
+
```

Review comment:
made consisitent
**File:** modules/gapi/test/executor/gtbbexecutor_internal_tests.cpp
**Change Type:** added
**Context:** PR #17851: Sole tbb executor
**Review Line:** 126

**Code Changes:**
```diff
+    using namespace cv::gimpl::parallel;
+    const int n = 10;
+    bool serial = true;
+    std::atomic<int> counter {0};
+    prio_items_queue_t q;
+    std::vector<tile_node> nodes; nodes.reserve(n+1);
+    const int invalid_order = -10;
+    std::vector<int> tiles_exec_order(n, invalid_order);
+
+    auto add_dependency_to = [](tile_node& node, tile_node& dependency) {
+        dependency.dependants.push_back(&node);
```

Review comment:
OK, no problem, I think :)
**File:** modules/gapi/src/executor/gtbbexecutor.cpp
**Change Type:** added
**Context:** PR #17851: Sole tbb executor
**Review Line:** 287

**Code Changes:**
```diff
+    //
+    struct task_body {
+        exec_ctx& ctx;
+
+        std::size_t push_ready_dependants(tile_node* node) const {
+            return graph::push_ready_dependants(ctx.q, node);
+        }
+
+        void spawn_clones(std::size_t items) const {
+            tasking::batch_spawn(items, ctx.root.get(), *this);
+        }
```

Review comment:
probably not particular reason for this. It is the matter of taste. I believe separating implementation (and low level details) this way keeps the logic a bit clear. As for the question why `task_body::operatot()` not made this way - the only reason as - it needs a copy of itself (`*this`)? so can not be made free-standing function
**File:** modules/gapi/include/opencv2/gapi/own/assert.hpp
**Change Type:** modified
**Context:** PR #17851: Sole tbb executor

**Code Changes:**
```diff
@@ -2,16 +2,28 @@
 // It is subject to the license terms in the LICENSE file found in the top-level directory
 // of this distribution and at http://opencv.org/license.html.
 //
-// Copyright (C) 2018 Intel Corporation
+// Copyright (C) 2018-2020 Intel Corporation
 
 
 #ifndef OPENCV_GAPI_OWN_ASSERT_HPP
 #define OPENCV_GAPI_OWN_ASSERT_HPP
```

Review comment:
AFAIK, expression is still should be computed by compiler (and then dead code is eliminated - but not all).
**File:** modules/gapi/src/executor/gtbbexecutor.cpp
**Change Type:** added
**Context:** PR #17851: Sole tbb executor

**Code Changes:**
```diff
@@ -0,0 +1,445 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+//
+// Copyright (C) 2020 Intel Corporation
+
+#include "gtbbexecutor.hpp"
+
+#if defined(HAVE_TBB)
```

Review comment:
By coding style constants / enums should be upper case. `NO` is a macro on some platforms (Apple). Consider using `bool` type instead. Enum doesn't look as necessary here.
**File:** modules/gapi/src/executor/gtbbexecutor.cpp
**Change Type:** added
**Context:** PR #17851: Sole tbb executor

**Code Changes:**
```diff
@@ -0,0 +1,445 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+//
+// Copyright (C) 2020 Intel Corporation
+
+#include "gtbbexecutor.hpp"
+
+#if defined(HAVE_TBB)
```

Review comment:
using meaningful names instead of faceless `true` / `false` , so `bool` is not an option :) will rename to UPPERCASE
**File:** modules/gapi/include/opencv2/gapi/own/assert.hpp
**Change Type:** modified
**Context:** PR #17851: Sole tbb executor

**Code Changes:**
```diff
@@ -2,16 +2,28 @@
 // It is subject to the license terms in the LICENSE file found in the top-level directory
 // of this distribution and at http://opencv.org/license.html.
 //
-// Copyright (C) 2018 Intel Corporation
+// Copyright (C) 2018-2020 Intel Corporation
 
 
 #ifndef OPENCV_GAPI_OWN_ASSERT_HPP
 #define OPENCV_GAPI_OWN_ASSERT_HPP
```

Review comment:
As `suppress_unused_warning(expr)` is the function call, it's actual argument i.e. `expr` _is_ calculated, then however it's value is discarded as bound to unnamed function argument. The `suppress_unused_warning` defined as: ```c++ template<typename T> void suppress_unused_warning( const T& ) {} ```
**File:** modules/gapi/include/opencv2/gapi/own/assert.hpp
**Change Type:** modified
**Context:** PR #17851: Sole tbb executor

**Code Changes:**
```diff
@@ -2,16 +2,28 @@
 // It is subject to the license terms in the LICENSE file found in the top-level directory
 // of this distribution and at http://opencv.org/license.html.
 //
-// Copyright (C) 2018 Intel Corporation
+// Copyright (C) 2018-2020 Intel Corporation
 
 
 #ifndef OPENCV_GAPI_OWN_ASSERT_HPP
 #define OPENCV_GAPI_OWN_ASSERT_HPP
```

Review comment:
All functions and methods are not "pure" in C++ standard ("pure" is GCC extension). So some non-inline `.type()` calls will be evaluated if they are part of this expr.
**File:** modules/gapi/include/opencv2/gapi/own/assert.hpp
**Change Type:** modified
**Context:** PR #17851: Sole tbb executor
**Review Line:** 26

**Code Changes:**
```diff
+
+#if defined _DEBUG || defined CV_STATIC_ANALYSIS
+#  define GAPI_DbgAssert CV_DbgAssert
+#else
+#  define GAPI_DbgAssert(expr) GAPI_DbgAssertNoOp(expr)
+#endif
 
 #else
 #include <stdexcept>
@@ -33,7 +45,7 @@ namespace detail
 
```

Review comment:
So what's the reason for all these changes?
**File:** modules/gapi/include/opencv2/gapi/own/assert.hpp
**Change Type:** modified
**Context:** PR #17851: Sole tbb executor
**Review Line:** 26

**Code Changes:**
```diff
+
+#if defined _DEBUG || defined CV_STATIC_ANALYSIS
+#  define GAPI_DbgAssert CV_DbgAssert
+#else
+#  define GAPI_DbgAssert(expr) GAPI_DbgAssertNoOp(expr)
+#endif
 
 #else
 #include <stdexcept>
@@ -33,7 +45,7 @@ namespace detail
 
```

Review comment:
the reason is - compiler warnings on release builds on unused variables in asserts
**File:** modules/gapi/include/opencv2/gapi/own/assert.hpp
**Change Type:** modified
**Context:** PR #17851: Sole tbb executor
**Review Line:** 26

**Code Changes:**
```diff
+
+#if defined _DEBUG || defined CV_STATIC_ANALYSIS
+#  define GAPI_DbgAssert CV_DbgAssert
+#else
+#  define GAPI_DbgAssert(expr) GAPI_DbgAssertNoOp(expr)
+#endif
 
 #else
 #include <stdexcept>
@@ -33,7 +45,7 @@ namespace detail
 
```

Review comment:
So, this unused variable is still going to be evaluated. Why we need that?
**File:** modules/gapi/include/opencv2/gapi/own/assert.hpp
**Change Type:** modified
**Context:** PR #17851: Sole tbb executor

**Code Changes:**
```diff
@@ -2,16 +2,28 @@
 // It is subject to the license terms in the LICENSE file found in the top-level directory
 // of this distribution and at http://opencv.org/license.html.
 //
-// Copyright (C) 2018 Intel Corporation
+// Copyright (C) 2018-2020 Intel Corporation
 
 
 #ifndef OPENCV_GAPI_OWN_ASSERT_HPP
 #define OPENCV_GAPI_OWN_ASSERT_HPP
```

Review comment:
Please follow the classic C `assert()` implementation from `assert.h` / `cassert` headers (it is "dbg" assert in OpenCV): https://en.cppreference.com/w/cpp/error/assert
**File:** modules/gapi/include/opencv2/gapi/own/assert.hpp
**Change Type:** modified
**Context:** PR #17851: Sole tbb executor

**Code Changes:**
```diff
@@ -2,16 +2,28 @@
 // It is subject to the license terms in the LICENSE file found in the top-level directory
 // of this distribution and at http://opencv.org/license.html.
 //
-// Copyright (C) 2018 Intel Corporation
+// Copyright (C) 2018-2020 Intel Corporation
 
 
 #ifndef OPENCV_GAPI_OWN_ASSERT_HPP
 #define OPENCV_GAPI_OWN_ASSERT_HPP
```

Review comment:
Having the assert implemented like this does not prevent "unused" warnings (and that is why it was not enough to use `CV_DbgAssert` as is and I had to re-invent it. )
**File:** modules/gapi/include/opencv2/gapi/own/assert.hpp
**Change Type:** modified
**Context:** PR #17851: Sole tbb executor
**Review Line:** 26

**Code Changes:**
```diff
+
+#if defined _DEBUG || defined CV_STATIC_ANALYSIS
+#  define GAPI_DbgAssert CV_DbgAssert
+#else
+#  define GAPI_DbgAssert(expr) GAPI_DbgAssertNoOp(expr)
+#endif
 
 #else
 #include <stdexcept>
@@ -33,7 +45,7 @@ namespace detail
 
```

Review comment:
It seems to me that actually evaluate the expression is the only reliable way to actually "use" variables it made of (and there fore silence those warnings). And yes compiling optimization of dead code removal is crucial here
**File:** modules/gapi/include/opencv2/gapi/own/assert.hpp
**Change Type:** modified
**Context:** PR #17851: Sole tbb executor
**Review Line:** 26

**Code Changes:**
```diff
+
+#if defined _DEBUG || defined CV_STATIC_ANALYSIS
+#  define GAPI_DbgAssert CV_DbgAssert
+#else
+#  define GAPI_DbgAssert(expr) GAPI_DbgAssertNoOp(expr)
+#endif
 
 #else
 #include <stdexcept>
@@ -33,7 +45,7 @@ namespace detail
 
```

Review comment:
> "unused" problem is in caller code. Not in assertion macro.
**File:** modules/gapi/include/opencv2/gapi/own/assert.hpp
**Change Type:** modified
**Context:** PR #17851: Sole tbb executor
**Review Line:** 26

**Code Changes:**
```diff
+
+#if defined _DEBUG || defined CV_STATIC_ANALYSIS
+#  define GAPI_DbgAssert CV_DbgAssert
+#else
+#  define GAPI_DbgAssert(expr) GAPI_DbgAssertNoOp(expr)
+#endif
 
 #else
 #include <stdexcept>
@@ -33,7 +45,7 @@ namespace detail
 
```

Review comment:
Unfortunately, no the problem is _in_ the macro. Here is a typical use case : ```c++ struct root_decrement_ref_count{ void operator()(tbb::task* t) const { auto result = t->decrement_ref_count(); ASSERT(result >= 1); } }; ``` This functor is used as RAII deleter for `unique::ptr`. Main Invariant of the code is that reference count of the TBB root task is not lesser that 1. This invariant is checked here. Reference count is atomic and the only safe way to get it's previous value save result of the `decrement_ref_count()` call (it Read-Modify-Write operation over atomic). The problem is that it is used only in the assertion and in the release mode it has to silenced explicitly, which is _ugly_ IMHO.
**File:** modules/gapi/include/opencv2/gapi/own/assert.hpp
**Change Type:** modified
**Context:** PR #17851: Sole tbb executor

**Code Changes:**
```diff
@@ -2,16 +2,28 @@
 // It is subject to the license terms in the LICENSE file found in the top-level directory
 // of this distribution and at http://opencv.org/license.html.
 //
-// Copyright (C) 2018 Intel Corporation
+// Copyright (C) 2018-2020 Intel Corporation
 
 
 #ifndef OPENCV_GAPI_OWN_ASSERT_HPP
 #define OPENCV_GAPI_OWN_ASSERT_HPP
```

Review comment:
it seems that `sizeof()` is the solution here. As it is silence the warning and does not evaluate it's argument
**File:** modules/gapi/include/opencv2/gapi/own/assert.hpp
**Change Type:** modified
**Context:** PR #17851: Sole tbb executor
**Review Line:** 26

**Code Changes:**
```diff
+
+#if defined _DEBUG || defined CV_STATIC_ANALYSIS
+#  define GAPI_DbgAssert CV_DbgAssert
+#else
+#  define GAPI_DbgAssert(expr) GAPI_DbgAssertNoOp(expr)
+#endif
 
 #else
 #include <stdexcept>
@@ -33,7 +45,7 @@ namespace detail
 
```

Review comment:
Just replace to C-like `assert()` and you will receive the same "unused" warning in release builds. Workaround for such cases: ```.diff -auto result = t->decrement_ref_count(); +auto result = t->decrement_ref_count(); (void)result; ASSERT(result >= 1); ```
**File:** modules/gapi/include/opencv2/gapi/own/assert.hpp
**Change Type:** modified
**Context:** PR #17851: Sole tbb executor

**Code Changes:**
```diff
@@ -2,16 +2,28 @@
 // It is subject to the license terms in the LICENSE file found in the top-level directory
 // of this distribution and at http://opencv.org/license.html.
 //
-// Copyright (C) 2018 Intel Corporation
+// Copyright (C) 2018-2020 Intel Corporation
 
 
 #ifndef OPENCV_GAPI_OWN_ASSERT_HPP
 #define OPENCV_GAPI_OWN_ASSERT_HPP
```

Review comment:
> it seems that sizeof() is the solution here. But not for lambdas :) - fixed to use `constexpr` and bool operations short-circuit evaluation
**File:** modules/gapi/include/opencv2/gapi/own/assert.hpp
**Change Type:** modified
**Context:** PR #17851: Sole tbb executor
**Review Line:** 26

**Code Changes:**
```diff
+
+#if defined _DEBUG || defined CV_STATIC_ANALYSIS
+#  define GAPI_DbgAssert CV_DbgAssert
+#else
+#  define GAPI_DbgAssert(expr) GAPI_DbgAssertNoOp(expr)
+#endif
 
 #else
 #include <stdexcept>
@@ -33,7 +45,7 @@ namespace detail
 
```

Review comment:
Yes, almost every problem can be workarounded :) ... but why if there is a proper solution to it ?
**File:** modules/gapi/src/executor/gtbbexecutor.cpp
**Change Type:** added
**Context:** PR #17851: Sole tbb executor
**Review Line:** 409

**Code Changes:**
```diff
+            auto async_work_done = [&ctx]() { return 0 == ctx.async_tasks.count; };
+            do {
+               // First participate in execution of TBB graph till there are no more ready tasks.
+               ctx.root->wait_for_all();
+
+               if (!async_work_done()) { // Wait on the conditional variable iff there is active async work
+                   auto start = timer.now();
+                   std::unique_lock<std::mutex> lk(ctx.async_tasks.mtx);
+                   // Wait (probably by sleeping) until all async tasks are completed or new TBB tasks are created.
+                   // FIXME: Use TBB resumable tasks here to avoid blocking TBB thread
+                   ctx.async_tasks.cv.wait(lk, [&]{return async_work_done() || !tbb_work_done() ;});
```

Review comment:
`iff` -> `if`
**File:** modules/gapi/src/executor/gtbbexecutor.cpp
**Change Type:** added
**Context:** PR #17851: Sole tbb executor
**Review Line:** 409

**Code Changes:**
```diff
+            auto async_work_done = [&ctx]() { return 0 == ctx.async_tasks.count; };
+            do {
+               // First participate in execution of TBB graph till there are no more ready tasks.
+               ctx.root->wait_for_all();
+
+               if (!async_work_done()) { // Wait on the conditional variable iff there is active async work
+                   auto start = timer.now();
+                   std::unique_lock<std::mutex> lk(ctx.async_tasks.mtx);
+                   // Wait (probably by sleeping) until all async tasks are completed or new TBB tasks are created.
+                   // FIXME: Use TBB resumable tasks here to avoid blocking TBB thread
+                   ctx.async_tasks.cv.wait(lk, [&]{return async_work_done() || !tbb_work_done() ;});
```

Review comment:
https://en.wikipedia.org/wiki/If_and_only_if
**File:** modules/gapi/include/opencv2/gapi/own/assert.hpp
**Change Type:** modified
**Context:** PR #17851: Sole tbb executor
**Review Line:** 26

**Code Changes:**
```diff
+
+#if defined _DEBUG || defined CV_STATIC_ANALYSIS
+#  define GAPI_DbgAssert CV_DbgAssert
+#else
+#  define GAPI_DbgAssert(expr) GAPI_DbgAssertNoOp(expr)
+#endif
 
 #else
 #include <stdexcept>
@@ -33,7 +45,7 @@ namespace detail
 
```

Review comment:
> if there is a proper solution It still evaluates expression. More complex and common cases looks like `ASSERT(node->isValid());`. Compiler's DCE can't remove that completely. --- Assertion macro must not evaluate passed expression (should be empty) in case of "noop". Do not confuse developers with new specific behavior.
**File:** modules/gapi/include/opencv2/gapi/own/assert.hpp
**Change Type:** modified
**Context:** PR #17851: Sole tbb executor
**Review Line:** 26

**Code Changes:**
```diff
+
+#if defined _DEBUG || defined CV_STATIC_ANALYSIS
+#  define GAPI_DbgAssert CV_DbgAssert
+#else
+#  define GAPI_DbgAssert(expr) GAPI_DbgAssertNoOp(expr)
+#endif
 
 #else
 #include <stdexcept>
@@ -33,7 +45,7 @@ namespace detail
 
```

Review comment:
Last version of the patch does not evaluate the expression (and not cause "unused" warning)
**File:** modules/gapi/include/opencv2/gapi/util/copy_through_move.hpp
**Change Type:** added
**Context:** PR #17851: Sole tbb executor
**Review Line:** 16

**Code Changes:**
```diff
+
+namespace cv
+{
+namespace util
+{
+    //This is a tool to move initialize captures of a lambda in C++11
+    template<typename T>
+    struct copy_through_move_t{
+       T value;
+       const T& get() const {return value;}
+       T&       get()       {return value;}
```

Review comment:
Check `gasync.cpp` for similar stuff. We really don't want to have duplicated code.
**File:** modules/gapi/src/executor/gtbbexecutor.cpp
**Change Type:** added
**Context:** PR #17851: Sole tbb executor
**Review Line:** 16

**Code Changes:**
```diff
+
+#include <opencv2/gapi/own/assert.hpp>
+#include <opencv2/gapi/util/copy_through_move.hpp>
+#include "logger.hpp" // GAPI_LOG
+
+#include <tbb/task.h>
+#include <memory> // unique_ptr
+
+#include <atomic>
+#include <condition_variable>
+
```

Review comment:
BTW, ``` note: ‘#pragma message: TBB Warning: tbb/task.h is deprecated. For details, please see Deprecated Features appendix in the TBB reference manual.’ ``` TBB (ver 2020.3 interface 11103)