Skip to content

Commit

Permalink
Started importing the fizz template for site + documentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
denisrosset committed Mar 22, 2016
1 parent 14e693b commit 6e28990
Show file tree
Hide file tree
Showing 17 changed files with 1,013 additions and 30 deletions.
109 changes: 83 additions & 26 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,44 +1,63 @@
import com.typesafe.sbt.site.util.SiteHelpers
import com.typesafe.sbt.SbtGhPages.GhPagesKeys._
import sbtunidoc.Plugin.UnidocKeys._

val scalaCheckVersion = "1.12.4"
val scalaTestVersion = "3.0.0-M7"
val spireVersion = "0.11.0"

// inspired by Spire build.sbt file
// custom keys used by sbt-site

lazy val tutorialSubDirName = settingKey[String]("Website tutorial directory")
lazy val apiSubDirName = settingKey[String]("Unidoc API directory")

// projects

lazy val metal = (project in file("."))
.settings(moduleName := "metal")
.settings(metalSettings: _*)
.settings(metalSettings)
.settings(noPublishSettings)
.aggregate(core, library, docs)
.dependsOn(core, library)

lazy val docs = (project in file("docs"))
.settings(moduleName := "metal-docs")
.settings(metalSettings)
.settings(noPublishSettings)
.aggregate(core, library)
.settings(tutConfig)
.settings(unidocConfig)
.settings(siteConfig)
.dependsOn(core, library)

lazy val core = (project in file("core"))
.settings(moduleName := "metal-core")
.settings(metalSettings: _*)
.settings(coreSettings: _*)
.settings(crossVersionSharedSources:_*)
.settings(commonJvmSettings:_*)
.settings(metalSettings)
.settings(crossVersionSharedSources)

lazy val library = (project in file("library"))
.settings(moduleName := "metal-library")
.settings(metalSettings: _*)
.settings(coreSettings: _*)
.settings(scalaTestSettings:_*)
.settings(metalSettings)
.settings(scalaTestSettings)
.settings(libraryDependencies += "org.scalacheck" %% "scalacheck" % scalaCheckVersion)
.settings(crossVersionSharedSources:_*)
.settings(commonJvmSettings:_*)
.settings(crossVersionSharedSources)
.dependsOn(core)

lazy val metalSettings = buildSettings ++ commonSettings ++ publishSettings

lazy val buildSettings = Seq(
name := "metal",
organization := "org.scala-metal",
scalaVersion := "2.11.8",
crossScalaVersions := Seq("2.10.6", "2.11.8")
)

lazy val commonSettings = Seq(
apiURL := Some(url("https://denisrosset.github.io/metal/latest/api")),
scmInfo := Some(ScmInfo(url("https://github.com/denisrosset/metal"), "scm:git:[email protected]:denisrosset/metal.git")),
scalacOptions in (Compile, doc) := (scalacOptions in (Compile, doc)).value.filter(_ != "-Xfatal-warnings"),
testOptions in Test += Tests.Argument(TestFrameworks.ScalaTest, "-oDF"),
scalacOptions ++= commonScalacOptions.diff(Seq(
"-Xfatal-warnings",
"-Xfatal-warnings",
"-language:existentials",
"-Ywarn-dead-code",
"-Ywarn-numeric-widen",
Expand All @@ -49,25 +68,15 @@ lazy val commonSettings = Seq(
Resolver.sonatypeRepo("snapshots")
),
libraryDependencies += "org.spire-math" %% "spire" % spireVersion
) ++ scalaMacroDependencies ++ warnUnusedImport

lazy val coreSettings = Seq(
buildInfoKeys := Seq[BuildInfoKey](version),
buildInfoPackage := "metal"
)
) ++ scalaMacroDependencies ++ warnUnusedImport ++ selectiveOptimize ++ doctestConfig

lazy val publishSettings = Seq(
homepage := None, // Some(url("http://scala-metal.org")),
homepage := Some(url("http://denisrosset.github.io/metal")),
licenses += ("MIT", url("http://opensource.org/licenses/MIT")),
bintrayRepository := "maven",
publishArtifact in Test := false
)

lazy val commonJvmSettings = Seq(
testOptions in Test += Tests.Argument(TestFrameworks.ScalaTest, "-oDF")
) ++ selectiveOptimize
// -optimize has no effect in scala-js other than slowing down the build

// do not optimize on Scala 2.10 because of optimizer bug, see SI-3882
lazy val selectiveOptimize =
scalacOptions ++= {
Expand All @@ -83,10 +92,58 @@ lazy val scalaTestSettings = Seq(
libraryDependencies += "org.scalatest" %% "scalatest" % scalaTestVersion % "test"
)

///////////////////////////////////////////////////////////////////////////////////////////////////
// Base documentation settings, taken from https://github.com/denisrosset/fizz

lazy val siteConfig = ghpages.settings ++ Seq(
siteMappings ++= Seq(
file("CONTRIBUTING.md") -> "contributing.md"
),
ghpagesNoJekyll := false,
git.remoteRepo := "[email protected]:denisrosset/metal.git",
includeFilter in makeSite := "*.html" | "*.css" | "*.png" | "*.jpg" | "*.gif" | "*.js" | "*.swf" | "*.yml" | "*.md"
)

lazy val doctestConfig = doctestSettings ++ Seq(
doctestTestFramework := DoctestTestFramework.ScalaTest, // opinion: we default to Scalatest
// the following two lines specify an explicit Scalatest version and tell sbt-doctest to
// avoid importing new dependencies
libraryDependencies ++= Seq(
"org.scalatest" %% "scalatest" % scalaTestVersion % "test",
"org.scalacheck" %% "scalacheck" % scalaCheckVersion % "test"
),
doctestWithDependencies := false
)

lazy val unidocConfig = unidocSettings ++ Seq(
apiSubDirName := "latest/api",
// sbt-site will use the generated documentation
addMappingsToSiteDir(mappings in (ScalaUnidoc, packageDoc), apiSubDirName),
// projects to include
unidocProjectFilter in (ScalaUnidoc, unidoc) := inProjects(core, library),
// enable automatic linking to the external Scaladoc of our own managed dependencies
autoAPIMappings := true,
scalacOptions in (ScalaUnidoc, unidoc) ++= Seq(
// we want warnings to be fatal (on broken links for example)
"-Xfatal-warnings",
// link to source code, yes that's an euro symbol
"-doc-source-url", scmInfo.value.get.browseUrl + "/tree/master€{FILE_PATH}.scala",
"-sourcepath", baseDirectory.in(LocalRootProject).value.getAbsolutePath,
// generate type hierarchy diagrams, runs graphviz
"-diagrams"
)
)

lazy val tutConfig = tutSettings ++ Seq(
tutorialSubDirName := "_tut",
addMappingsToSiteDir(tut, tutorialSubDirName),
tutScalacOptions ~= (_.filterNot(Set("-Ywarn-unused-import", "-Ywarn-dead-code")))
)

////////////////////////////////////////////////////////////////////////////////////////////////////
// Base Build Settings - Should not need to edit below this line.
//
// Taken from the common keys acrros various Typelevel projects, see e.g. cats
// Taken from the common keys across various Typelevel projects, see e.g. cats

lazy val noPublishSettings = Seq(
publish := (),
Expand Down
30 changes: 30 additions & 0 deletions docs/src/main/tut/containers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
layout: default
title: "Container types"
section: "tutorials"
---

# Container types

All container names are prefixed by one of:

- `M`: the mutable variant,
- `I`: the immutable variant,
- `F`: the generic variant, that can be either mutable or immutable.

The following set implementations are provided (where `x = M/I/F`):

- `xHashSet[K]`: a set implemented using an open addressing scheme,
- `xSortedSet[K]`: a sorted set, using the `Order` type class from `Spire`,
- `xBitSet[Int]` a bitset implementation with (non-negative) `Int` keys.

Two variants of maps are implemented:

- `xHashMap[K,V]`: an hash map using an open addressing scheme,
- `xHashMap2[K,V1,V2]`: an hash map usin an open addressing scheme, storing
values `(V1, V2)`; however, the values of type `V1` and `V2` are never
stored as a tuple to avoid allocations; individual access methods are
provided instead.

There is also a work-in-progress implementation of mutable and growable arrays
`Buffer` and an immutable wrapper for arrays `IArraySeq`.
42 changes: 42 additions & 0 deletions docs/src/main/tut/higherorder.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
layout: default
title: "Higher-order functions"
section: "tutorials"
---

# Higher-order functions

Several higher-order functions are available on containers, for example `foreach`, `count`,
`exists`, `forall`, `foldLeft` (or `/:`); however, the calling convention is slightly different
from the Scala collections to avoid allocating tuples:

```scala
val m = MHashMap(1 -> 2, 3 -> 4)
m.foreach { (k, v) => println(s"($k, $v)") }

// instead of

m.foreach { case (k, v) => println(s"($k, $v)") }
```

The methods `min`, `max`, `sum`, `product` are also available; the required algebraic
operations (orders, additive monoids, multiplicative monoids) are provided using
Spire type classes. Contrary to the standard Scala library, Spire is heavily
specialized on primitive types.

Those higher-order functions are implemented using implicit classes and macros, to
avoid polluting the container interfaces.

At compilation time, a call such as `m.foreach { (k, v) => println(k) }` is inlined,
producing code similar to:

```scala
@inline def rec(ptr: Ptr[m.Tag, m.Cap]): Unit = ptr match {
case IsVPtr(vp) =>
val k = m.ptrKey[Int](vp)
val v = m.ptrValue[Int](vp)
println(k)
rec(m.ptrNext(vp))
case _ =>
}
```
70 changes: 70 additions & 0 deletions docs/src/main/tut/ptr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
layout: default
title: "Pointers"
section: "tutorials"
source: "core/src/main/scala/metal/Ptr.scala"
scaladoc: "#metal.Ptr"
---

# Pointers

Metal defines two pointer types, `Ptr` and `VPtr`. The `Ptr` pointer can either point
to an element in a container, or be a null pointer. The `VPtr` pointer is guaranteed to point
to an element.

Pointers are invalidated when the container is modified, with the exception of the
`removeAndAdvance` methods.

A pointer has a single type parameters, representing the singleton type of the pointed collection. Pointers
are implemented using value classes containing a primitive `Long`.

Most of the container methods return possibly null `Ptr` instances. To convert a `Ptr`
to a `VPtr`, the following syntax is encouraged:

```tut
import metal._
val container = mutable.HashSet(1, 2, 3)
val p = container.ptr
p match {
case IsVPtr(vp) =>
// now `vp` is a `VPtr`
println(vp.key)
case _ =>
println("container is empty")
}
```

Thanks to name-based extractors, the code snippet above does not perform any allocations.

Several methods are implemented on `Ptr` and `VPtr`, and can be used to access the pointed
element.

```scala
import metal._
import metal.syntax._

val m = mutable.HashMap(1 -> 2, 3 -> 4)
// we request a pointer to the first element in the map (hash maps have an internal arbitrary order)
val p = m.ptr
assert(!p.isNull)
assert(p.nonNull)
assert(p.keyOrElse(-1) > 0)
// does not throw, `sys.error` is inlined by macros and only called when `p` is null
p.keyOrElse(sys.error("")) > 0
// same syntax for pointed values
p.valueOrElse(-1)
p match {
case IsVPtr(vp) =>
// vp is now a non-null `VPtr`, the pointed key is available
assert(vp.key > 0)
assert(vp.value % 2 == 0)
// we can ask for a (possibly null) pointer to the next element, according
// to the hash map internal order
val nxt = vp.next
case _ =>
}
// we can look for keys
val p1 = m.ptrFind(3)
// and the same methods are available on that pointer
assert(p1.nonNull)
```
3 changes: 3 additions & 0 deletions docs/src/main/tut/tutorials.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Tutorials

Some tutorials are provided to help you using the metal library.
16 changes: 16 additions & 0 deletions docs/src/site/_config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: Metal documentation
projectname: Metal
markdown: kramdown
highlighter: rouge
baseurl: /metal
apidocs: /metal/latest/api
githuburl: https://github.com/denisrosset/metal
sources: https://github.com/denisrosset/metal/blob/master/
# logourl: https://pbs.twimg.com/profile_images/3005141692/dc8e1eb36b6cbd2b5726f63c50adf7f2.png # uncomment with a real image
# chatname: Gitter
# chaturl: https://gitter.im/...
# buildname: Travis
# buildurl: https://travis-ci.org/...
collections:
tut:
output: true
Loading

0 comments on commit 6e28990

Please sign in to comment.