<commit_before>/*
 * Copyright 2016 Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 *  Copyright (c) 2015, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 *
 */
#pragma once

#include <folly/Conv.h>
#include <boost/function_types/is_member_pointer.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/mpl/equal.hpp>
#include <boost/mpl/pop_front.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/vector.hpp>

namespace folly {

// Auto-conversion of key/value based on callback signature, documented in
// DynamicParser.h.
namespace detail {
class IdentifyCallable {
public:
  enum class Kind { Function, MemberFunction };
  template <typename Fn>
  constexpr static Kind getKind() { return test<Fn>(nullptr); }
private:
  template <typename Fn>
  using IsMemFn = typename boost::function_types::template is_member_pointer<
    decltype(&Fn::operator())
  >;
  template <typename Fn>
  constexpr static typename std::enable_if<IsMemFn<Fn>::value, Kind>::type
  test(IsMemFn<Fn>*) { return IdentifyCallable::Kind::MemberFunction; }
  template <typename>
  constexpr static Kind test(...) { return IdentifyCallable::Kind::Function; }
};

template <IdentifyCallable::Kind, typename Fn>
struct ArgumentTypesByKind {};
template <typename Fn>
struct ArgumentTypesByKind<IdentifyCallable::Kind::MemberFunction, Fn> {
  using type = typename boost::mpl::template pop_front<
    typename boost::function_types::template parameter_types<
      decltype(&Fn::operator())
    >::type
  >::type;
};
template <typename Fn>
struct ArgumentTypesByKind<IdentifyCallable::Kind::Function, Fn> {
  using type = typename boost::function_types::template parameter_types<Fn>;
};

template <typename Fn>
using ArgumentTypes =
  typename ArgumentTypesByKind<IdentifyCallable::getKind<Fn>(), Fn>::type;

// At present, works for lambdas or plain old functions, but can be
// extended.  The comparison deliberately strips cv-qualifieers and
// reference, leaving that choice up to the caller.
template <typename Fn, typename... Args>
constexpr bool hasArgumentTypes() {
  using HasArgumentTypes = typename boost::mpl::template equal<
    typename boost::mpl::template transform<
      typename boost::mpl::template transform<
        ArgumentTypes<Fn>,
        typename std::template remove_reference<boost::mpl::_1>
      >::type,
      typename std::template remove_cv<boost::mpl::_1>
    >::type,
    boost::mpl::vector<Args...>
  >::type;
  return HasArgumentTypes::value;
}
template <typename... Args>
using EnableForArgTypes =
  typename std::enable_if<hasArgumentTypes<Args...>(), void>::type;

// No arguments
template <typename Fn> EnableForArgTypes<Fn>
invokeForKeyValue(Fn f, const folly::dynamic&, const folly::dynamic&) {
  f();
}

// 1 argument -- pass only the value
//
// folly::dynamic (no conversion)
template <typename Fn> EnableForArgTypes<Fn, folly::dynamic>
invokeForKeyValue(Fn fn, const folly::dynamic&, const folly::dynamic& v) {
  fn(v);
}
// int64_t
template <typename Fn> EnableForArgTypes<Fn, int64_t><commit_msg>Work around an MSVC expression SFINAE bug in DynamicParser<commit_after>/*
 * Copyright 2016 Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 *  Copyright (c) 2015, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 *
 */
#pragma once

#include <folly/Conv.h>
#include <boost/function_types/is_member_pointer.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/mpl/equal.hpp>
#include <boost/mpl/pop_front.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/vector.hpp>

namespace folly {

// Auto-conversion of key/value based on callback signature, documented in
// DynamicParser.h.
namespace detail {
class IdentifyCallable {
public:
  enum class Kind { Function, MemberFunction };
  template <typename Fn>
  constexpr static Kind getKind() { return test<Fn>(nullptr); }
private:
  template <typename Fn>
  using IsMemFn = typename boost::function_types::template is_member_pointer<
    decltype(&Fn::operator())
  >;
  template <typename Fn>
  constexpr static typename std::enable_if<IsMemFn<Fn>::value, Kind>::type
  test(IsMemFn<Fn>*) { return IdentifyCallable::Kind::MemberFunction; }
  template <typename>
  constexpr static Kind test(...) { return IdentifyCallable::Kind::Function; }
};

template <IdentifyCallable::Kind, typename Fn>
struct ArgumentTypesByKind {};
template <typename Fn>
struct ArgumentTypesByKind<IdentifyCallable::Kind::MemberFunction, Fn> {
  using type = typename boost::mpl::template pop_front<
    typename boost::function_types::template parameter_types<
      decltype(&Fn::operator())
    >::type
  >::type;
};
template <typename Fn>
struct ArgumentTypesByKind<IdentifyCallable::Kind::Function, Fn> {
  using type = typename boost::function_types::template parameter_types<Fn>;
};

template <typename Fn>
using ArgumentTypes =
  typename ArgumentTypesByKind<IdentifyCallable::getKind<Fn>(), Fn>::type;

// At present, works for lambdas or plain old functions, but can be
// extended.  The comparison deliberately strips cv-qualifieers and
// reference, leaving that choice up to the caller.
template <typename Fn, typename... Args>
struct HasArgumentTypes
    : boost::mpl::template equal<
          typename boost::mpl::template transform<
              typename boost::mpl::template transform<
                  ArgumentTypes<Fn>,
                  typename std::template remove_reference<boost::mpl::_1>>::
                  type,
              typename std::template remove_cv<boost::mpl::_1>>::type,
          boost::mpl::vector<Args...>>::type {};
template <typename... Args>
using EnableForArgTypes =
    typename std::enable_if<HasArgumentTypes<Args...>::value, void>::type;

// No arguments
template <typename Fn> EnableForArgTypes<Fn>
invokeForKeyValue(Fn f, const folly::dynamic&, const folly::dynamic&) {
  f();
}

// 1 argument -- pass only the value
//
// folly::dynamic (no conversion)
template <typename Fn> EnableForArgTypes<Fn, folly::dynamic>
invokeForKeyValue(Fn fn, const folly::dynamic&, const folly::dynamic& v) {
  fn(v);
}
// int64_t
template <typename Fn> EnableForArgTypes<Fn, int64_t>
{'fraction_non_alphanumeric': 0.1143418467583497, 'fraction_numerical': 0.004977079240340537, 'mean_word_length': 4.639586410635155, 'pattern_counts': {'":': 0, '<': 91, '<?xml version=': 0, '>': 91, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5380553', 'n_tokens_mistral': 2255, 'n_tokens_neox': 2166, 'n_words': 711}