<commit_before>/*
 * Copyright (c) 2012-14 <NAME>, <NAME>
 *
 * 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.
 */

package shapeless

import scala.language.experimental.macros

import scala.reflect.macros.whitebox

trait Generic[T] {
  type Repr
  def to(t : T) : Repr
  def from(r : Repr) : T
}

trait LowPriorityGeneric {
  implicit def apply[T]: Generic[T] = macro GenericMacros.materialize[T]
}

object Generic extends LowPriorityGeneric {
  type Aux[T, Repr0] = Generic[T] { type Repr = Repr0 }

  // Refinement for products, here we can provide the calling context with
  // a proof that the resulting Repr <: HList
  implicit def product[T <: Product]: Generic[T] = macro GenericMacros.materializeForProduct[T]
}

trait LabelledGeneric[T] {
  type Repr
  def to(t : T) : Repr
  def from(r : Repr) : T
}

trait LowPriorityLabelledGeneric {
  implicit def apply[T]: LabelledGeneric[T] = macro GenericMacros.materializeLabelled[T]
}

object LabelledGeneric extends LowPriorityLabelledGeneric {
  type Aux[T, Out0] = LabelledGeneric[T]{ type Repr = Out0 }

  // Refinement for products, here we can provide the calling context with
  // a proof that the resulting Repr is a record
  implicit def product[T <: Product]: LabelledGeneric[T] = macro GenericMacros.materializeLabelledForProduct[T]
}

class GenericMacros(val c: whitebox.Context) {
  import c.universe._

  def materialize[T](implicit tT: WeakTypeTag[T]) =
    materializeAux(false, false, tT.tpe)

  def materializeForProduct[T <: Product](implicit tT: WeakTypeTag[T]) =
    materializeAux(true, false, tT.tpe)

  def materializeLabelled[T](implicit tT: WeakTypeTag[T]) =
    materializeAux(false, true, tT.tpe)

  def materializeLabelledForProduct[T <: Product](implicit tT: WeakTypeTag[T]) =
    materializeAux(true, true, tT.tpe)

  def materializeAux(product: Boolean, labelled: Boolean, tpe: Type): Tree = {
    import c.{ abort, enclosingPosition, typeOf }

    if (product && tpe <:< typeOf[Coproduct])
      abort(enclosingPosition, s"Cannot materialize Coproduct $tpe as a Product")

    val helper = new Helper(tpe, product, labelled, labelled)
    if (tpe <:< typeOf[HList] || tpe <:< typeOf[Coproduct])
      helper.materializeIdentityGeneric<commit_msg>Use fundep materialization. Minor cleanups. Fixes #106. Fixes #108.<commit_after>/*
 * Copyright (c) 2012-14 <NAME>, <NAME>
 *
 * 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.
 */

package shapeless

import scala.language.experimental.macros

import scala.reflect.macros.whitebox

trait Generic[T] {
  type Repr
  def to(t : T) : Repr
  def from(r : Repr) : T
}

object Generic {
  type Aux[T, Repr0] = Generic[T] { type Repr = Repr0 }

  def apply[T](implicit gen: Generic[T]): Aux[T, gen.Repr] = gen

  implicit def materialize[T, R]: Aux[T, R] = macro GenericMacros.materialize[T, R]
}

trait LabelledGeneric[T] extends Generic[T]

object LabelledGeneric {
  type Aux[T, Repr0] = LabelledGeneric[T]{ type Repr = Repr0 }

  def apply[T](implicit lgen: LabelledGeneric[T]): Aux[T, lgen.Repr] = lgen

  implicit def materialize[T, R]: Aux[T, R] = macro GenericMacros.materializeLabelled[T, R]
}

class GenericMacros(val c: whitebox.Context) {
  import c.universe._

  def materialize[T: WeakTypeTag, R: WeakTypeTag] =
    materializeAux(false, weakTypeOf[T], weakTypeOf[R])

  def materializeLabelled[T: WeakTypeTag, R: WeakTypeTag] =
    materializeAux(true, weakTypeOf[T], weakTypeOf[R])

  def materializeAux(labelled: Boolean, tpe: Type, rTpe: Type): Tree = {
    import c.{ abort, enclosingPosition, typeOf }

    val helper = new Helper(tpe, false, labelled, labelled)
    if (tpe <:< typeOf[HList] || tpe <:< typeOf[Coproduct])
      helper.materializeIdentityGeneric
{'fraction_non_alphanumeric': 0.10536357854568582, 'fraction_numerical': 0.007207971168115328, 'mean_word_length': 4.307086614173229, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '5440242', 'n_tokens_mistral': 1569, 'n_tokens_neox': 1519, 'n_words': 489}