00001 //------------------------------------------------------------------------------ 00002 // Copyright (c) 2011-2017 by European Organization for Nuclear Research (CERN) 00003 // Author: Krzysztof Jamrog <krzysztof.piotr.jamrog@cern.ch>, 00004 // Michal Simon <michal.simon@cern.ch> 00005 //------------------------------------------------------------------------------ 00006 // This file is part of the XRootD software suite. 00007 // 00008 // XRootD is free software: you can redistribute it and/or modify 00009 // it under the terms of the GNU Lesser General Public License as published by 00010 // the Free Software Foundation, either version 3 of the License, or 00011 // (at your option) any later version. 00012 // 00013 // XRootD is distributed in the hope that it will be useful, 00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 // GNU General Public License for more details. 00017 // 00018 // You should have received a copy of the GNU Lesser General Public License 00019 // along with XRootD. If not, see <http://www.gnu.org/licenses/>. 00020 // 00021 // In applying this licence, CERN does not waive the privileges and immunities 00022 // granted to it by virtue of its status as an Intergovernmental Organization 00023 // or submit itself to any jurisdiction. 00024 //------------------------------------------------------------------------------ 00025 00026 #ifndef __XRD_CL_OPERATION_PARAMS_HH__ 00027 #define __XRD_CL_OPERATION_PARAMS_HH__ 00028 00029 #include "XrdCl/XrdClFwd.hh" 00030 00031 #include <string> 00032 #include <sstream> 00033 #include <unordered_map> 00034 00035 namespace XrdCl 00036 { 00037 00038 //---------------------------------------------------------------------------- 00040 //---------------------------------------------------------------------------- 00041 template<typename T> 00042 class ArgBase 00043 { 00044 public: 00045 00046 //------------------------------------------------------------------------ 00048 //------------------------------------------------------------------------ 00049 ArgBase() 00050 { 00051 } 00052 00053 //------------------------------------------------------------------------ 00055 //------------------------------------------------------------------------ 00056 virtual ~ArgBase() 00057 { 00058 } 00059 00060 //------------------------------------------------------------------------ 00064 //------------------------------------------------------------------------ 00065 ArgBase( T value ) : holder( new PlainValue( std::move( value ) ) ) 00066 { 00067 } 00068 00069 //------------------------------------------------------------------------ 00073 //------------------------------------------------------------------------ 00074 ArgBase( std::future<T> &&ftr ) : holder( new FutureValue( std::move( ftr ) ) ) 00075 { 00076 } 00077 00078 //------------------------------------------------------------------------ 00082 //------------------------------------------------------------------------ 00083 ArgBase( const Fwd<T> &fwd ) : holder( new FwdValue( fwd ) ) 00084 { 00085 } 00086 00087 //------------------------------------------------------------------------ 00089 //------------------------------------------------------------------------ 00090 ArgBase( ArgBase &&arg ) : holder( std::move( arg.holder ) ) 00091 { 00092 } 00093 00094 //------------------------------------------------------------------------ 00096 //------------------------------------------------------------------------ 00097 T Get() 00098 { 00099 if( !holder ) throw std::logic_error( "XrdCl::ArgBase::Get(): value not set." ); 00100 return holder->Get(); 00101 } 00102 00103 protected: 00104 00105 //------------------------------------------------------------------------ 00107 //------------------------------------------------------------------------ 00108 struct ValueHolder 00109 { 00110 //---------------------------------------------------------------------- 00112 //---------------------------------------------------------------------- 00113 virtual ~ValueHolder() 00114 { 00115 } 00116 00117 //---------------------------------------------------------------------- 00119 //---------------------------------------------------------------------- 00120 virtual T Get() = 0; 00121 }; 00122 00123 //------------------------------------------------------------------------ 00125 //------------------------------------------------------------------------ 00126 struct PlainValue : public ValueHolder 00127 { 00128 //-------------------------------------------------------------------- 00132 //-------------------------------------------------------------------- 00133 PlainValue( T &&value ) : value( std::move( value ) ) 00134 { 00135 } 00136 00137 //-------------------------------------------------------------------- 00139 //-------------------------------------------------------------------- 00140 T Get() 00141 { 00142 return std::move( value ); 00143 } 00144 00145 private: 00146 //-------------------------------------------------------------------- 00148 //-------------------------------------------------------------------- 00149 T value; 00150 }; 00151 00152 //------------------------------------------------------------------------ 00154 //------------------------------------------------------------------------ 00155 struct FutureValue : public ValueHolder 00156 { 00157 //-------------------------------------------------------------------- 00161 //-------------------------------------------------------------------- 00162 FutureValue( std::future<T> &&ftr ) : ftr( std::move( ftr ) ) 00163 { 00164 } 00165 00166 //-------------------------------------------------------------------- 00168 //-------------------------------------------------------------------- 00169 T Get() 00170 { 00171 return ftr.get(); 00172 } 00173 00174 private: 00175 //-------------------------------------------------------------------- 00177 //-------------------------------------------------------------------- 00178 std::future<T> ftr; 00179 }; 00180 00181 //------------------------------------------------------------------------ 00183 //------------------------------------------------------------------------ 00184 struct FwdValue : public ValueHolder 00185 { 00186 //-------------------------------------------------------------------- 00190 //-------------------------------------------------------------------- 00191 FwdValue( const Fwd<T> &fwd ) : fwd( fwd ) 00192 { 00193 } 00194 00195 //-------------------------------------------------------------------- 00197 //-------------------------------------------------------------------- 00198 T Get() 00199 { 00200 return std::move( *fwd ); 00201 } 00202 00203 private: 00204 //-------------------------------------------------------------------- 00206 //-------------------------------------------------------------------- 00207 Fwd<T> fwd; 00208 }; 00209 00210 //------------------------------------------------------------------------ 00212 //------------------------------------------------------------------------ 00213 std::unique_ptr<ValueHolder> holder; 00214 }; 00215 00216 //---------------------------------------------------------------------------- 00221 //---------------------------------------------------------------------------- 00222 template<typename T> 00223 class Arg : public ArgBase<T> 00224 { 00225 public: 00226 00227 //------------------------------------------------------------------------ 00229 //------------------------------------------------------------------------ 00230 Arg() 00231 { 00232 } 00233 00234 //------------------------------------------------------------------------ 00238 //------------------------------------------------------------------------ 00239 Arg( T value ) : ArgBase<T>( std::move( value ) ) 00240 { 00241 } 00242 00243 //------------------------------------------------------------------------ 00247 //------------------------------------------------------------------------ 00248 Arg( std::future<T> &&ftr ) : ArgBase<T>( std::move( ftr ) ) 00249 { 00250 } 00251 00252 //------------------------------------------------------------------------ 00256 //------------------------------------------------------------------------ 00257 Arg( const Fwd<T> &fwd ) : ArgBase<T>( fwd ) 00258 { 00259 } 00260 00261 //------------------------------------------------------------------------ 00263 //------------------------------------------------------------------------ 00264 Arg( Arg &&arg ) : ArgBase<T>( std::move( arg ) ) 00265 { 00266 } 00267 00268 //------------------------------------------------------------------------ 00270 //------------------------------------------------------------------------ 00271 Arg& operator=( Arg &&arg ) 00272 { 00273 if( &arg == this ) return *this; 00274 this->holder = std::move( arg.holder ); 00275 return *this; 00276 } 00277 }; 00278 00279 //---------------------------------------------------------------------------- 00283 //---------------------------------------------------------------------------- 00284 template<> 00285 class Arg<std::string> : public ArgBase<std::string> 00286 { 00287 public: 00288 00289 //------------------------------------------------------------------------ 00291 //------------------------------------------------------------------------ 00292 Arg() 00293 { 00294 } 00295 00296 //------------------------------------------------------------------------ 00300 //------------------------------------------------------------------------ 00301 Arg( std::string str ) : ArgBase<std::string>( str ) 00302 { 00303 } 00304 00305 //------------------------------------------------------------------------ 00309 //------------------------------------------------------------------------ 00310 Arg( const char *cstr ) : ArgBase<std::string>( cstr ) 00311 { 00312 } 00313 00314 //------------------------------------------------------------------------ 00316 //------------------------------------------------------------------------ 00317 Arg( std::future<std::string> &&ftr ) : ArgBase<std::string>( std::move( ftr ) ) 00318 { 00319 } 00320 00321 //------------------------------------------------------------------------ 00323 //------------------------------------------------------------------------ 00324 Arg( const Fwd<std::string> &fwd ) : ArgBase<std::string>( fwd ) 00325 { 00326 } 00327 00328 00329 //------------------------------------------------------------------------ 00331 //----------------------------------------------------------------------- 00332 Arg( Arg &&arg ) : ArgBase<std::string>( std::move( arg ) ) 00333 { 00334 } 00335 00336 //------------------------------------------------------------------------ 00338 //------------------------------------------------------------------------ 00339 Arg& operator=( Arg &&arg ) 00340 { 00341 if( &arg == this ) return *this; 00342 this->holder = std::move( arg.holder ); 00343 return *this; 00344 } 00345 }; 00346 } 00347 00348 #endif // __XRD_CL_OPERATION_PARAMS_HH__