//------------------------------------------------------------------------------ // Copyright (c) 2011-2017 by European Organization for Nuclear Research (CERN) // Author: Krzysztof Jamrog , // Michal Simon //------------------------------------------------------------------------------ // This file is part of the XRootD software suite. // // XRootD 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 3 of the License, or // (at your option) any later version. // // XRootD 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 General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with XRootD. If not, see . // // In applying this licence, CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. //------------------------------------------------------------------------------ #ifndef __XRD_CL_OPERATION_PARAMS_HH__ #define __XRD_CL_OPERATION_PARAMS_HH__ #include "XrdCl/XrdClFwd.hh" #include "XrdCl/XrdClOptional.hh" #include #include #include #include namespace XrdCl { //---------------------------------------------------------------------------- //! Base class for Arg. //---------------------------------------------------------------------------- template class ArgBase { public: //------------------------------------------------------------------------ //! Default Constructor. //------------------------------------------------------------------------ ArgBase() { } //------------------------------------------------------------------------ //! Destructor. //------------------------------------------------------------------------ virtual ~ArgBase() { } //------------------------------------------------------------------------ //! Constructor //! //! @param value : the value of the argument //------------------------------------------------------------------------ ArgBase( T value ) : holder( new PlainValue( std::move( value ) ) ) { } //------------------------------------------------------------------------ //! Constructor. //! //! @param ftr : future value of the argument //------------------------------------------------------------------------ ArgBase( std::future &&ftr ) : holder( new FutureValue( std::move( ftr ) ) ) { } //------------------------------------------------------------------------ //! Constructor. //! //! @param fwd : forwarded value of the argument //------------------------------------------------------------------------ ArgBase( const Fwd &fwd ) : holder( new FwdValue( fwd ) ) { } //------------------------------------------------------------------------ //! Get Constructor. //------------------------------------------------------------------------ ArgBase( ArgBase &&arg ) : holder( std::move( arg.holder ) ) { } //------------------------------------------------------------------------ //! @return : value of the argument //------------------------------------------------------------------------ inline T& Get() const { if( !holder ) throw std::logic_error( "XrdCl::ArgBase::Get(): value not set." ); return holder->Get(); } operator T() const { return Get(); } protected: //------------------------------------------------------------------------ //! Abstract class for holding a value //------------------------------------------------------------------------ struct ValueHolder { //---------------------------------------------------------------------- //! Virtual Destructor (important ;-). //---------------------------------------------------------------------- virtual ~ValueHolder() { } //---------------------------------------------------------------------- //! @return : the value //---------------------------------------------------------------------- virtual T& Get() = 0; }; //------------------------------------------------------------------------ //! A helper class for holding plain value //------------------------------------------------------------------------ struct PlainValue : public ValueHolder { //-------------------------------------------------------------------- //! Constructor //! //! @param value : the value to be hold by us //-------------------------------------------------------------------- PlainValue( T &&value ) : value( std::move( value ) ) { } //-------------------------------------------------------------------- //! @return : the value //-------------------------------------------------------------------- T& Get() { return value; } private: //-------------------------------------------------------------------- //! the value //-------------------------------------------------------------------- T value; }; //------------------------------------------------------------------------ //! A helper class for holding future value //------------------------------------------------------------------------ struct FutureValue : public ValueHolder { //-------------------------------------------------------------------- //! Constructor //! //! @param ftr : the future value to be hold by us //-------------------------------------------------------------------- FutureValue( std::future &&ftr ) : ftr( std::move( ftr ) ) { } //-------------------------------------------------------------------- //! @return : the value //-------------------------------------------------------------------- T& Get() { if( val ) return *val; val = ftr.get(); return *val; } private: //-------------------------------------------------------------------- //! the future value //-------------------------------------------------------------------- std::future ftr; Optional val; }; //------------------------------------------------------------------------ //! A helper class for holding forwarded value //------------------------------------------------------------------------ struct FwdValue : public ValueHolder { //-------------------------------------------------------------------- //! Constructor //! //! @param fwd : the forwarded value to be hold by us //-------------------------------------------------------------------- FwdValue( const Fwd &fwd ) : fwd( fwd ) { } //-------------------------------------------------------------------- //! @return : the value //-------------------------------------------------------------------- T& Get() { return *fwd; } private: //-------------------------------------------------------------------- //! the forwarded value //-------------------------------------------------------------------- Fwd fwd; }; //------------------------------------------------------------------------ //! Holds the value of the argument //------------------------------------------------------------------------ std::unique_ptr holder; }; //---------------------------------------------------------------------------- //! Operation argument. //! The argument is optional, user may initialize it with 'notdef' //! //! @arg T : real type of the argument //---------------------------------------------------------------------------- template class Arg : public ArgBase { public: //------------------------------------------------------------------------ //! Default Constructor. //------------------------------------------------------------------------ Arg() { } //------------------------------------------------------------------------ //! Constructor. //! //! @param value : value of the argument (will be std::moved) //------------------------------------------------------------------------ Arg( T value ) : ArgBase( std::move( value ) ) { } //------------------------------------------------------------------------ //! Constructor. //! //! @param ftr : future value of the argument (will be std::moved) //------------------------------------------------------------------------ Arg( std::future &&ftr ) : ArgBase( std::move( ftr ) ) { } //------------------------------------------------------------------------ //! Constructor. //! //! @param fwd : forwarded value of the argument (will be std::moved) //------------------------------------------------------------------------ Arg( const Fwd &fwd ) : ArgBase( fwd ) { } //------------------------------------------------------------------------ //! Get Constructor. //------------------------------------------------------------------------ Arg( Arg &&arg ) : ArgBase( std::move( arg ) ) { } //------------------------------------------------------------------------ //! Get-Assignment. //------------------------------------------------------------------------ Arg& operator=( Arg &&arg ) { if( &arg == this ) return *this; this->holder = std::move( arg.holder ); return *this; } }; //---------------------------------------------------------------------------- //! Operation argument. //! Specialized for 'std::string', might be constructed in addition from c-like //! string (const char*) //---------------------------------------------------------------------------- template<> class Arg : public ArgBase { public: //------------------------------------------------------------------------ //! Default Constructor. //------------------------------------------------------------------------ Arg() { } //------------------------------------------------------------------------ //! Constructor. //! //! @param str : value of the argument //------------------------------------------------------------------------ Arg( std::string str ) : ArgBase( str ) { } //------------------------------------------------------------------------ //! Constructor. //! //! @param cstr : value of the argument //------------------------------------------------------------------------ Arg( const char *cstr ) : ArgBase( cstr ) { } //------------------------------------------------------------------------ //! Constructor. //------------------------------------------------------------------------ Arg( std::future &&ftr ) : ArgBase( std::move( ftr ) ) { } //------------------------------------------------------------------------ //! Constructor. //------------------------------------------------------------------------ Arg( const Fwd &fwd ) : ArgBase( fwd ) { } //------------------------------------------------------------------------ //! Get Constructor. //----------------------------------------------------------------------- Arg( Arg &&arg ) : ArgBase( std::move( arg ) ) { } //------------------------------------------------------------------------ //! Get-Assignment. //------------------------------------------------------------------------ Arg& operator=( Arg &&arg ) { if( &arg == this ) return *this; this->holder = std::move( arg.holder ); return *this; } }; } #endif // __XRD_CL_OPERATION_PARAMS_HH__