1 /*!
2  * \file   ThreadedTaskResult.hxx
3  * \brief
4  * \author Thomas Helfer
5  * \date   19 juin 2016
6  * \copyright Copyright (C) 2006-2018 CEA/DEN, EDF R&D. All rights
7  * reserved.
8  * This project is publicly released under either the GNU GPL Licence
9  * or the CECILL-A licence. A copy of thoses licences are delivered
10  * with the sources of TFEL. CEA or EDF may also distribute this
11  * project under specific licensing conditions.
12  */
13 
14 #ifndef LIB_TFEL_SYSTEM_THREADEDTASKRESULT_HXX
15 #define LIB_TFEL_SYSTEM_THREADEDTASKRESULT_HXX
16 
17 #include<exception>
18 #include<type_traits>
19 #include"TFEL/Config/TFELConfig.hxx"
20 
21 namespace tfel{
22 
23   namespace system{
24 
25     //! non-template base class of the ThreadedTaskResult class
26     struct TFELSYSTEM_VISIBILITY_EXPORT ThreadedTaskResultBase
27     {
28     protected:
29       //! thr
30       TFEL_NORETURN static void throwBadCastException();
31       //! thr
32       TFEL_NORETURN static void throwNullException();
33     }; // end of struct ThreadedTaskResultBase
34     /*!
35      * \brief a class standing for the result of a taks
36      *
37      * Its interface is loosely base on the interface of
38      * std::optional (not available in C++11), but it also stores an
39      * std::exception_ptr if .
40      */
41     template<typename T>
42     struct ThreadedTaskResult
43       : public ThreadedTaskResultBase
44     {
45       //! \brief default constructor
46       TFEL_INLINE ThreadedTaskResult();
47       /*!
48        * \brief constructor of T
49        * \param[in] args: arguments to T constructor
50        */
51       template<typename... Args>
52       TFEL_INLINE ThreadedTaskResult(Args&&...);
53       /*!
54        * \brief constructor of T
55        */
56       TFEL_INLINE ThreadedTaskResult(const T&);
57       //! \brief move constructor
58       TFEL_INLINE ThreadedTaskResult(ThreadedTaskResult&&);
59       //! \brief copy constructor
60       TFEL_INLINE ThreadedTaskResult(const ThreadedTaskResult&);
61       //! \brief assignement
62       TFEL_INLINE ThreadedTaskResult& operator=(const ThreadedTaskResult&);
63       //! \brief move assignement
64       TFEL_INLINE ThreadedTaskResult& operator=(ThreadedTaskResult&&);
65       //! \brief assignement
66       TFEL_INLINE ThreadedTaskResult& operator=(const T&);
67       //! \brief move assignement
68       TFEL_INLINE ThreadedTaskResult& operator=(T&&);
69       //! \brief set current exception
70       TFEL_INLINE void setException(const std::exception_ptr&);
71       //! \brief throw the catched exception
72 #ifndef _MSC_VER
73       TFEL_NORETURN TFEL_INLINE void rethrow();
74 #else /* _MSC_VER */
75       TFEL_INLINE void rethrow();
76 #endif /* _MSC_VER */
77 	  //! \brief conversion to bool
78       TFEL_INLINE operator bool () const;
79       //! \brief conversion to underlying type
80       TFEL_INLINE T& operator* ();
81       //! \brief conversion to underlying type
82       TFEL_INLINE const T& operator* () const;
83       //! \brief conversion to underlying type
84       TFEL_INLINE T* operator-> ();
85       //! \brief conversion to underlying type
86       TFEL_INLINE const T* operator-> () const;
87       //! \brief destructor
88       TFEL_INLINE ~ThreadedTaskResult();
89     private:
90       /*!
91        * build an object
92        * \param[in] args: arguments to the constructor
93        */
94       template<typename... Args>
95       TFEL_INLINE void build(Args&&...);
96       //! \brief clear the underlying object destructor
97       TFEL_INLINE void clear();
98       //! \brief pointer the underlying object storage
99       TFEL_INLINE T* get_pointer();
100       //! \brief pointer the underlying object storage
101       TFEL_INLINE const T* get_pointer() const;
102       //! \brief if true, the ThreadedTaskResult contains a value
103       bool initialized = false;
104       //! \brief storage of the underlying value
105       typename std::aligned_storage<sizeof(T),alignof(T)>::type storage;
106       //! exception ptr thrown during the task
107       std::exception_ptr eptr;
108     };
109 
110     //! Partial specialisation for non-returning tasks
111     template<>
112     struct TFELSYSTEM_VISIBILITY_EXPORT ThreadedTaskResult<void>
113       : public ThreadedTaskResultBase
114     {
115       //! \brief default constructor
116       ThreadedTaskResult();
117       //! \brief move constructor
118       ThreadedTaskResult(ThreadedTaskResult&&);
119       //! \brief copy constructor
120       ThreadedTaskResult(const ThreadedTaskResult&);
121       //! \brief assignement
122       ThreadedTaskResult& operator=(const ThreadedTaskResult&);
123       //! \brief move assignement
124       ThreadedTaskResult& operator=(ThreadedTaskResult&&);
125       //! \brief set current exception
126       void setException(const std::exception_ptr&);
127       //! \brief throw the catched exception
128       TFEL_NORETURN void rethrow();
129       //! \brief conversion to bool
130       operator bool () const;
131       //! \brief destructor
132       ~ThreadedTaskResult();
133     private:
134       //! exception ptr thrown during the task
135       std::exception_ptr eptr;
136     };
137 
138   } // end of namespace system
139 
140 } // end of namespace tfel
141 
142 #include"TFEL/System/ThreadedTaskResult.ixx"
143 
144 #endif /* LIB_TFEL_SYSTEM_THREADEDTASKRESULT_HXX */
145