comment tile_location friendships more thoroughly
make tile_location and obj_or_tile_id LessThanComparable and ostreamable

Useful for experimenting with different map types and for debugging.
Make an object's zboxes each store a ptr not ObjectIdentifier.

ztree_node:
-  unordered_set<ObjectIdentifier> objects_here;
+  unordered_set<pair<const ObjectIdentifier, bounding_box> const*>
                                   objects_here;

The pointer points into bbox_collision_detector<>::bboxes_by_object_.
bboxes_by_object_'s members have exactly the right lifetime for this
purpose.
While std::unordered_map *iterators* can be invalidated by inserting
into the container, *pointers* to key/value pairs in it cannot:

n3337 23.2.5 Unordered associative containers [unord.req]
  13. "The insert and emplace members shall not affect the validity
    of references to container elements, but may invalidate all
    iterators to the container. The erase members shall invalidate
    only iterators and references to the erased elements."


This change saves a lot of space* and makes most scenarios a bit faster.
*specifically:
  in 64bits,
  object_or_tile_identifier is currently 32 bytes (due to alignment
    taking its toll in several places), whereas a pointer is just 8 bytes.
  A given object can appear eight times in the ztree, potentially
    multiplying this wasted space: (32-8)=24, 24*8 = up to 192 bytes
    per elem.
Also, this change means not having to do lookups in bboxes_by_object_
  sometimes, which saves a bit of time.
Use poor-man's compiler feature detection in utils.hpp

We should also prefer to use CMake try_compile,
thus the #ifndef LASERCAKE_BUILD_SYSTEM_DID_FEATURE_DETECTION,
though I haven't implemented that yet.

The #ifdefs will work with any build system, but are not
as robust as feature-detection is.

Also deleted typedef __int128_t large_t; as large_t was unused,
rather than convert it.
fix latent zbox overflow bug (for larger bits/dims sizes than we use)
fix test indentation
Make the default build parallelism more generally reasonable (3)

Many people compiling have dual-cores. This can saturate most of
a quad-core.  I can keep it changed locally to the best number
for my machine.
Be more paranoid about struct unspecified_bool_ being imaginary.
Make a bit of bbox_collision_detector code clearer
Make ostream tuples say ", " not ","

(added a space character)

This means that when locale
(main() std::cerr.imbue(std::locale(""));)
puts commas in large numbers,
one can still tell what is going on.
clarify bbox_collision_detector code
Don't implement numeric_limits<bounds_checked_int>. (comments only)

Implementing it helped boost::random distributions use it as a type
somewhat, but then it added a signed integer constant (1) with an
unsigned bounds_checked_int type and didn't compile anyway.
(Further, I'm not interested in bounds-checking third-party code
like that. I may find another way to proceed than
using bounds_checked_int as template argument.)
get_un_bounds_checked_int() -> get_primitive_int() etc

These functions are mainly used in order to use a library
that doesn't get along with the bounds-checked types.
If we use Boost.Units there will be a similar issue
which I suspect may cause problems in most of the same
situations.  So I chose a new, shorter name to describe
this purpose of giving a number to somewhere that needs
primitive int types.

(Downside: It's not as long and ugly a name as
get_un_bounds_checked_*.  But being a function call at all
should discourage people writing unnecessary un-bounds-checking
of things!)
Fix bounds_checked_int compile

Running it alas tends to crash after a couple frames with Boost 1.49.0;
its Boost.Random has a bug that's fixed in SVN.

uniform_int_distribution with output type signed and more bits wide
than the generator unsigned type, and a distribution range including
negative numbers, sometimes produces max unsigned int as an answer.

(We could work around by using only 64-bit generators or only
32-bit ranges, or some other scheme, or use newer Boost (currently svn),
or worse hacks...)

the boost bug-fixing diff -u is thus:
--- /usr/include/boost/random/detail/signed_unsigned_tools.hpp
+++ boost-trunk-svn/boost/random/detail/signed_unsigned_tools.hpp
@@ -73,7 +73,7 @@
     if (y >= 0)
       return T2(x) + y;
     // y < 0
-    if (x >= T1(-(y+1)))  // result >= 0 after subtraction
+    if (x > T1(-(y+1)))  // result >= 0 after subtraction
       // avoid the nasty two's complement edge case for y == min()
       return T2(x - T1(-(y+1)) - 1);
     // abs(x) < abs(y), thus T2 able to represent x
add some tests for ostreamability
consistently use "friend inline" for ostream<< functions
Use hash_value() and ADL for hashes

following Boost and n3333.  A Boost svn revision required
having the hash_value(), not just the std specialization,
which prompted me.
Clang/standard compatibility

(explicit template instantiations must be in the original namespace
of the template they instantiate.)