 
   # trim_leading
 
+  def trim_leading(string) when is_binary(string) do
+    do_trim_leading(string)
+  end
+
   for codepoint <- whitespace do
-    def trim_leading(unquote(codepoint) <> rest), do: trim_leading(rest)
-  end
-  def trim_leading(""), do: ""
-  def trim_leading(string) when is_binary(string), do: string
+    def do_trim_leading(<<unquote(codepoint), rest::bits>>), do: do_trim_leading(rest)
+  end
+  def do_trim_leading(<<rest::bits>>), do: rest
 
   # trim_trailing
 


  # Downcase

  def downcase(string), do: downcase(string, "")

  for {codepoint, _upper, lower, _title} <- codes, lower && lower != codepoint do
    defp downcase(unquote(codepoint) <> rest, acc) do
      downcase(rest, acc <> unquote(lower))
    end
  end

  defp downcase(<<char, rest::binary>>, acc) do
    downcase(rest, <<acc::binary, char>>)
  end



  # Upcase

  def upcase(string) when is_binary(string), do: upcase(string, "")

  for {codepoint, upper, _lower, _title} <- codes, upper && upper != codepoint do
    defp upcase(<<unquote(codepoint), rest::bits>>, acc) do
      upcase(rest, acc <> unquote(upper))
    end
  end

  defp upcase(<<char, rest::bits>>, acc) do
    upcase(rest, <<acc::binary, char>>)
  end

