<commit_before>// Copyright (c) 2016-2020 <NAME> and Dr. <NAME>
// Please see LICENSE for license or visit https://github.com/taocpp/taopq/

#ifndef TAO_PQ_INTERNAL_PARAMETER_TRAITS_HPP
#define TAO_PQ_INTERNAL_PARAMETER_TRAITS_HPP

#include <cstddef>
#include <optional>
#include <tuple>
#include <type_traits>
#include <utility>

#include <libpq-fe.h>

#include <tao/pq/internal/gen.hpp>
#include <tao/pq/internal/parameter_traits_helper.hpp>
#include <tao/pq/null.hpp>

namespace tao::pq::internal
{
   template< template< typename... > class Traits, typename T, typename = void >
   struct parameter_traits
      : Traits< T >
   {
      using Traits< T >::Traits;
   };

   template< template< typename... > class Traits >
   struct parameter_traits< Traits, null_t >
   {
      explicit parameter_traits( const null_t& /*unused*/ ) noexcept
      {}

      static constexpr std::size_t columns = 1;

      template< std::size_t I >
      [[nodiscard]] static constexpr Oid type() noexcept
      {
         return 0;
      }

      template< std::size_t I >
      [[nodiscard]] static constexpr const char* value() noexcept
      {
         return nullptr;
      }

      template< std::size_t I >
      [[nodiscard]] static constexpr int length() noexcept
      {
         return 0;
      }

      template< std::size_t I >
      [[nodiscard]] static constexpr int format() noexcept
      {
         return 0;
      }
   };

   template< template< typename... > class Traits >
   struct parameter_traits< Traits, const char* >
      : char_pointer_helper
   {
      explicit parameter_traits( const char* p ) noexcept
         : char_pointer_helper( p )
      {}
   };

   template< template< typename... > class Traits, typename T >
   struct parameter_traits< Traits, std::optional< T > >
   {
   private:
      using U = parameter_traits< Traits, std::decay_t< T > >;
      std::optional< U > m_forwarder;

   public:
      explicit parameter_traits( const std::optional< T >& v )
      {
         if( v ) {
            m_forwarder.emplace( *v );
         }
      }

      explicit parameter_traits( std::optional< T >&& v )
      {
         if( v ) {
            m_forwarder.emplace( std::move( *v ) );
         }
      }

      static constexpr std::size_t columns = U::columns;

      template< std::size_t I >
      [[nodiscard]] static constexpr Oid type() noexcept
      {
         return U::template type< I >();
      }

      template< std::size_t I >
      [[nodiscard]] constexpr const char* value() const noexcept( noexcept( m_forwarder ? m_forwarder->template value< I >() : nullptr ) )
      {
         return m_forwarder ? m_forwarder->template value< I >() : nullptr;
      }

      template< std::size_t I >
      [[nodiscard]] constexpr int length() const noexcept( noexcept( m_forwarder ? m_forwarder->template length< I >() : 0 ) )
      {
         return m_forwarder ? m_forwarder->template length< I >() : 0;
      }

      template< std::size_t I >
      [[nodiscard]] static constexpr int format() noexcept
      {
         return U::template format< I >();
      }
   };

   template< template< typename... > class Traits, typename... Ts >
   struct parameter_traits< Traits, std::tuple< Ts... > >
   {
   private:
      using tuple_t = std::tuple< parameter_traits< Traits, std::decay_t< Ts > >... >;
      tuple_t m_tuple;

      using gen = internal::gen< parameter_traits< Traits, std::decay_t< Ts > >::columns... >;

   public:
      explicit parameter_traits( const std::tuple< Ts... >& tuple ) noexcept( noexcept( tuple_t( tuple ) ) )
         : m_tuple( tuple )
      {}

      explicit parameter_traits( std::tuple< Ts... >&& tuple ) noexcept( noexcept( tuple_t( std::move( tuple ) ) ) )
         : m_tuple( std::move( tuple ) )
      {}

      static constexpr std::size_t columns = ( 0 + ... + parameter_traits< Traits, std::decay_t< Ts > >::columns );

      template< std::size_t I >
      [[nodiscard]] constexpr Oid type() const noexcept( noexcept( std::get< gen::template outer< I > >( m_tuple ).template type< gen::template inner< I > >() ) )
      {
         return std::get< gen::template outer< I > >( m_tuple ).template type< gen::template inner< I > >();
      }

      template< std::size_t I >
      [[nodiscard]] const char* value() const noexcept( noexcept( std::get< gen::template outer< I > >( m_tuple ).template value< gen::template inner< I > >() ) )
      {
         return std::get< gen::template outer< I > >( m_tuple ).template value< gen::template inner< I > >();
      }

      template< std::size_t I >
      [[nodiscard]] constexpr int length() const noexcept( noexcept( std::get< gen::template outer< I > >( m_tuple ).template length< gen::template inner< I > >() ) )
      {
         return std::get< gen::template outer< I > >( m_tuple ).template length< gen::template inner< I > >();
      }

      template< std::size_t I >
      [[nodiscard]] constexpr int format() const noexcept( noexcept( std::get< gen::template outer< I > >( m_tuple ).template format< gen::template inner< I > >() ) )
      {
         return std::get< gen::template outer< I > >( m_tuple ).template format< gen::template inner< I > >();
      }
   };

   // default free function to detect member function to_taopq_param()
   template< typename T >
   auto to_taopq_param( const T& t ) noexcept( noexcept( t.to_taopq_param() ) )
      -> decltype( t.to_taopq_param() )
   {
      return t.to_taopq_param();
   }

   template< typename T >
   struct parameter_holder
   {
      using result_t = decltype( to_taopq_param( std::declval< const T& >() ) );
      const result_t result;

      explicit parameter_holder( const T& t ) noexcept( noexcept( result_t( to_taopq_param( t ) ) ) )
         : result( to_taopq_param( t ) )
      {}
   };

   template< template< typename... > class Traits, typename T >
   struct parameter_traits< Traits, T, std::void_t< decltype( to_taopq_param( std::declval< const T& >() ) ) > >
      : private parameter_holder< T >, public parameter_traits< Traits, typename parameter_holder< T >::result_t >
   {
      using typename parameter_holder< T >::result_t;

      explicit parameter_traits( const T& t ) noexcept( noexcept( parameter_holder< T >( t ), parameter_traits< Traits, result_t >( this->result ) ) )<commit_msg>Fix compile on older GCC<commit_after>// Copyright (c) 2016-2020 <NAME> and Dr. <NAME>
// Please see LICENSE for license or visit https://github.com/taocpp/taopq/

#ifndef TAO_PQ_INTERNAL_PARAMETER_TRAITS_HPP
#define TAO_PQ_INTERNAL_PARAMETER_TRAITS_HPP

#include <cstddef>
#include <optional>
#include <tuple>
#include <type_traits>
#include <utility>

#include <libpq-fe.h>

#include <tao/pq/internal/gen.hpp>
#include <tao/pq/internal/parameter_traits_helper.hpp>
#include <tao/pq/null.hpp>

namespace tao::pq::internal
{
   template< template< typename... > class Traits, typename T, typename = void >
   struct parameter_traits
      : Traits< T >
   {
      using Traits< T >::Traits;
   };

   template< template< typename... > class Traits >
   struct parameter_traits< Traits, null_t >
   {
      explicit parameter_traits( const null_t& /*unused*/ ) noexcept
      {}

      static constexpr std::size_t columns = 1;

      template< std::size_t I >
      [[nodiscard]] static constexpr Oid type() noexcept
      {
         return 0;
      }

      template< std::size_t I >
      [[nodiscard]] static constexpr const char* value() noexcept
      {
         return nullptr;
      }

      template< std::size_t I >
      [[nodiscard]] static constexpr int length() noexcept
      {
         return 0;
      }

      template< std::size_t I >
      [[nodiscard]] static constexpr int format() noexcept
      {
         return 0;
      }
   };

   template< template< typename... > class Traits >
   struct parameter_traits< Traits, const char* >
      : char_pointer_helper
   {
      explicit parameter_traits( const char* p ) noexcept
         : char_pointer_helper( p )
      {}
   };

   template< template< typename... > class Traits, typename T >
   struct parameter_traits< Traits, std::optional< T > >
   {
   private:
      using U = parameter_traits< Traits, std::decay_t< T > >;
      std::optional< U > m_forwarder;

   public:
      explicit parameter_traits( const std::optional< T >& v )
      {
         if( v ) {
            m_forwarder.emplace( *v );
         }
      }

      explicit parameter_traits( std::optional< T >&& v )
      {
         if( v ) {
            m_forwarder.emplace( std::move( *v ) );
         }
      }

      static constexpr std::size_t columns = U::columns;

      template< std::size_t I >
      [[nodiscard]] static constexpr Oid type() noexcept
      {
         return U::template type< I >();
      }

      template< std::size_t I >
      [[nodiscard]] constexpr const char* value() const noexcept( noexcept( m_forwarder ? m_forwarder->template value< I >() : nullptr ) )
      {
         return m_forwarder ? m_forwarder->template value< I >() : nullptr;
      }

      template< std::size_t I >
      [[nodiscard]] constexpr int length() const noexcept( noexcept( m_forwarder ? m_forwarder->template length< I >() : 0 ) )
      {
         return m_forwarder ? m_forwarder->template length< I >() : 0;
      }

      template< std::size_t I >
      [[nodiscard]] static constexpr int format() noexcept
      {
         return U::template format< I >();
      }
   };

   template< template< typename... > class Traits, typename... Ts >
   struct parameter_traits< Traits, std::tuple< Ts... > >
   {
   private:
      using tuple_t = std::tuple< parameter_traits< Traits, std::decay_t< Ts > >... >;
      tuple_t m_tuple;

      using gen = internal::gen< parameter_traits< Traits, std::decay_t< Ts > >::columns... >;

   public:
      explicit parameter_traits( const std::tuple< Ts... >& tuple ) noexcept( noexcept( tuple_t( tuple ) ) )
         : m_tuple( tuple )
      {}

      explicit parameter_traits( std::tuple< Ts... >&& tuple ) noexcept( noexcept( tuple_t( std::move( tuple ) ) ) )
         : m_tuple( std::move( tuple ) )
      {}

      static constexpr std::size_t columns = ( 0 + ... + parameter_traits< Traits, std::decay_t< Ts > >::columns );

      template< std::size_t I >
      [[nodiscard]] constexpr Oid type() const noexcept( noexcept( std::get< gen::template outer< I > >( m_tuple ).template type< gen::template inner< I > >() ) )
      {
         return std::get< gen::template outer< I > >( m_tuple ).template type< gen::template inner< I > >();
      }

      template< std::size_t I >
      [[nodiscard]] const char* value() const noexcept( noexcept( std::get< gen::template outer< I > >( m_tuple ).template value< gen::template inner< I > >() ) )
      {
         return std::get< gen::template outer< I > >( m_tuple ).template value< gen::template inner< I > >();
      }

      template< std::size_t I >
      [[nodiscard]] constexpr int length() const noexcept( noexcept( std::get< gen::template outer< I > >( m_tuple ).template length< gen::template inner< I > >() ) )
      {
         return std::get< gen::template outer< I > >( m_tuple ).template length< gen::template inner< I > >();
      }

      template< std::size_t I >
      [[nodiscard]] constexpr int format() const noexcept( noexcept( std::get< gen::template outer< I > >( m_tuple ).template format< gen::template inner< I > >() ) )
      {
         return std::get< gen::template outer< I > >( m_tuple ).template format< gen::template inner< I > >();
      }
   };

   // default free function to detect member function to_taopq_param()
   template< typename T >
   auto to_taopq_param( const T& t ) noexcept( noexcept( t.to_taopq_param() ) )
      -> decltype( t.to_taopq_param() )
   {
      return t.to_taopq_param();
   }

   template< typename T >
   struct parameter_holder
   {
      using result_t = decltype( to_taopq_param( std::declval< const T& >() ) );
      const result_t result;

      explicit parameter_holder( const T& t ) noexcept( noexcept( result_t( to_taopq_param( t ) ) ) )
         : result( to_taopq_param( t ) )
      {}
   };

   template< template< typename... > class Traits, typename T >
   struct parameter_traits< Traits, T, std::void_t< decltype( to_taopq_param( std::declval< const T& >() ) ) > >
      : private parameter_holder< T >, public parameter_traits< Traits, typename parameter_holder< T >::result_t >
   {
      using typename parameter_holder< T >::result_t;

      explicit parameter_traits( const T& t ) noexcept( noexcept( parameter_holder< T >( t ), parameter_traits< Traits, result_t >( std::declval< result_t >() ) ) )
{'fraction_non_alphanumeric': 0.13646798068550622, 'fraction_numerical': 0.0023747328425552127, 'mean_word_length': 2.711515863689777, 'pattern_counts': {'":': 0, '<': 220, '<?xml version=': 0, '>': 231, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3096872', 'n_tokens_mistral': 4153, 'n_tokens_neox': 3959, 'n_words': 1095}