WeakKeyDict cache implementation

It turns out that some FiniteElements have __slots__ set. This uses a
weak key dictionary to implement a non-leaking cache instead of
caching FIAT elements directly on the UFL ones.