/*!
 * \file   /utl/impl/crtp.h
 * \brief  CRTP idiom support header
 *
 * Copyright (C) 2018 Christos Choutouridis
 *
 * This program 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.
 *
 * This program 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
#ifndef __utl_impl_crtp_h__
#define __utl_impl_crtp_h__

#include <utl/core/impl.h>

/*!
 * \defgroup crtp   CRTP idiom support header
 * \ingroup  impl
 *
 *  utl supports both CRTP idiom and dynamic polymorphism. By default
 *  CRTP is the preferred way. If the user need virtuals then instead of
 *  CRTP type, the \ref virtual_tag can passed to base class. The rest
 *  will handled by utl automatically.
 */
//!@{
namespace utl {
   //! CRTP support tag type
   struct crtp_tag { };
   //! virtual support tag type
   struct virtual_tag { };

   //! \def CRTP boilerplate lines
   #define _CRTP_IMPL(T) \
      constexpr T& impl() { return *static_cast<T*>(this); } \
      constexpr const T& impl() const { return *static_cast<const T*>(this); }

}
//!@}
#endif /* __utl_impl_crtp_h__ */
