SwiftUI conforming to Hashable - swiftui

How can we make a SwiftUI object, Image, in particular, conform to Hashable protocol?
I know they conform to the Equatable protocol, so the main question would be how to get a Hash value, or use the hash(into:) function?

In Swift, conforming to the Hashable protocol is often just as easy as adding Hashable to your conformance list. However, if you have custom requirements, or use properties that don’t all conform to Hashable, it takes a little more work.
Here’s an example struct we can work with:
struct iPad: Hashable {
var serialNumber: String
var capacity: Int
}
Because that conforms to the Hashable protocol and both its properties also conform to the Hashable protocol, Swift will generate a hash(into:) method automatically.
However, in this case we can see that serialNumber is enough to identify each iPad uniquely so hashing capacity isn’t needed. So, we can write our own implementation of hash(into:) that hashes just that one property:
func hash(into hasher: inout Hasher) {
hasher.combine(serialNumber)
}
You can add more properties to your hash by calling combine() repeatedly, and the order in which you add properties affects the finished hash value.
Swift uses a random seed every time it hashes an object, which means the hash value for any object is effectively guaranteed to be different between runs of your app.
This in turn means that elements you add to a set or a dictionary are highly likely to have a different order each time you run your app.
Source: https://www.hackingwithswift.com/example-code/language/how-to-conform-to-the-hashable-protocol
This may also be of help as well.

Related

NEAR Indexer Framework - Raw data instead of String for view types

It appears the NEAR Indexer framework do different transformations (i.e. FunctionCall#args) for presenting the data to developer wrapping NEAR primitives types into View type.
It turns for example the FunctionCall#args field from a Vec<u8> to a String by doing a base64 encoding of the value. For the DeployContract, it gives the hash of the data. And others like that.
Is it possible to access the raw data instead of the view and avoid those conversions?
There is no way around it at the moment. Eventually, Indexer Framework should introduce its own structs and avoid coupling with the view structs.

Creating a generalized resource map without using strings?

Let's assume I want to create an object that will hold some arbitrary data.
// Pseudocode
class MyContainer {
map<key, pair<void*, size>>;
}
The key in this case also identifies the kind of data stored in the void* (e.g an image, a struct of some kind, maybe even a function).
The most general way to del with this is have the key be a string. Then you can put whatever on earth you want and then you can just read it. As a silly example, the key can just be:
"I am storing a png image and the source file was at location/assets/image.png and today is sunday".
i.e you can encode whatever you want. This is however slow. A much faster alternative is using enumerators and your keys are then IMAGE, HASHMAP, FUNCTION, THE_ANSWER_TO_LIFE...
However that requires you know every single case you need to handle beforehand and create an enumerator for it manually (which is tedious and not very extensible).
Is there a compromise that can be made? i.e something that uses only one key but is faster than strings and more extensible than enums?
Edit:
The exact use case I am trying to use this for is as a generalized storage for rendering data. This includes images, vertex buffers, volumetric data, lighting information... Or any other conceivable thing you may need.
The only way I know to create "absolute polymorphism" (i.e represent literally any form of conceivable data) is to use void pointers and rely on algorithms to understand the data.
Example:
Say our key is a JSON string where the key of each element is the name of a field in a compact struct and the value is the offset in bytes.
E.g
{
m_field1: 0,
m_field2: 32,
m_field3: 128,
}
Then to access any of the elements in the void* all you need to do is do symbol manipulation to get the number and then ptr + offset.
You can do the same with a set of unique identifiers (enums) and associated functions that get you the fields based on the identifier (hard coded approach).
Hopefully this makes the question less obscure.

Fill CapnProto List with non-primitive

According to the CapnProto documentation: (NOTE: I am using the C++ version)
For List where Foo is a non-primitive type, the type returned by
operator[] and iterator::operator*() is Foo::Reader (for
List::Reader) or Foo::Builder (for List::Builder). The
builder’s set method takes a Foo::Reader as its second parameter.
While using "set" seems to work fine for non-primitive types:
Other stack overflow question for primitives only
There does not appear to be a "set" function for automatically generated lists of non-primitives. Did my CapnProto generation fail in some way, or is there another method for setting elements in a list of non-primitives?
There is a "set" method, but it is called setWithCaveats():
destListBuilder.setWithCaveats(index, sourceStructReader)
This is to let you know that there are some obscure problems with setting an element of a struct list. The problem stems from the fact that struct lists are not represented as a list of pointers as you might expect, but rather they are a "flattened" series of consecutive structs, all of the same size. This implies that space for all the structs in the list is allocated at the time that you initialize the list. So, when you call setWithCaveats(), the target space is already allocated previously, and you're copying the source struct into that space.
This presents a problem in the face of varying versions: the source struct might have been constructed using a newer version of the protocol, in which additional fields were defined. In this case, it may actually be larger than expected. But, the destination space was already allocated, based on the protocol version you compiled with. So, it's too small! Unfortunately, there's no choice but to discard the newly-defined fields that we don't know about. Hence, data may be lost.
Of course, it may be that in your application, you know that the struct value doesn't come from a newer version, or that you don't care if you lose fields that you don't know about. In this case, setWithCaveats() will do what you want.
If you want to be careful to preserve unknown fields, you may want to look into the method capnp::Orphanage::newOrphanConcat(). This method can concatenate a list of lists of struct readers into a single list in such a way that no data is lost -- the target list is allocated with each struct's size equal to the maximum of all input structs.
auto orphanage = Orphanage::getForMessageContaining(builder);
auto orphan = orphanage.newOrphanConcat({list1Reader, list2Reader});
builder.adoptListField(kj::mv(orphan));

Where can I find a list of string use to access aggregate data?

When we declare a computed property OR an observer we do the following,
fullName: Ember.computed('firstName', 'lastName', function() {
return `${this.get('firstName')} ${this.get('lastName')}`;
})
We first declare a string which stands for the value we need to the observer; however, these are the simplest way to observe some value.
There are cases we need to observe array's length or the content inside it.
I know we can use arrayName.[] to observer the length of the array but I would like to know where can I find a detailed reference on how to use these string thing to get what I want.
Currently, everything still feels magical to me, for example, I do not really understand what arrayName.#each do.
You can read more about computed property and how to use the string to represent aggregate data at,
https://guides.emberjs.com/v2.11.0/object-model/computed-properties-and-aggregate-data/
The common ones are
arrayName.#each.propertyName, to observe the property for each element inside array
However, this only work one level deep and you cannot use nested form.
arrayName.[], to observe the length of array.

How does one implement a container which exposes multiple ranges?

I have a container which (among other things) exposes a string buffer, and the upper case version of that string buffer. (Well, it isn't just upper case, but it is similar in concept) I want to allow a caller to do something similar to:
container c("Example");
auto const iter = c.begin() + 2;
std::printf("%c\n", iter->get_source()); // Prints a
std::printf("%c\n", iter->get_upper()); // Prints A
iter->set('x');
std::puts(c.get()); // Prints Exxmple
std::puts(c.get_upper()); // Prints EXXMPLE
The problem is, the "proxy" type with the member functions get_source, get_upper, etc. has no obvious place it can be stored, and an iterator is required to return a reference to something, not a value. (vector<bool> has a similar problem)
Alternately I could expose some kind of shell container or range, or expose completely separate iterator begin/end functions. Does anyone have experience doing something like this and know what works well?
My personal approach to this sort of things is to use property maps: I envision a system of algorithms which can [optionally] take a property map (or actually sometimes multiple property maps) for each range. The idea is that *it yields a key (e.g., the T& it currently do) which is then used with a property map which transforms the key into the actually accessed value. The transformation can, e.g., be the identity yielding the current behavior of the algorithms and a good default to be used when there is no property map. The example above would look something like this:
auto const cursor = c.begin();
std::printf("%c\n", c.map_source()(*cursor));
std::printf("%c\n", c.map_upper()(*cursor));
c.map_source()(*cursor, 'x');
std::copy(c.map_source(), c, std::ostreambuf_iterator<char>(std::cout));
std::copy(c.map_upper(), c, std::ostreambuf_iterator<char>(std::cout));
std::copy([](unsigned char c)->char{ return std::toupper(c); }, c,
std::ostreambuf_iterator<char>(std::cout));
The code assumes that the property maps yielding the source and the capitalized characters are obtained using c.map_source() and c.map_upper(), respectively. The last variant using std::copy() uses a lambda function as a property map.
Sadly, I still haven't found the time to write up a coherent proposal to apply various improvements to the STL algorithms. ... nor do I have have an implementation putting it all together (I have a somewhat clunky implementation which is about 10 years old and doesn't benefit from various C++11 features which make it a lot easier; also, this implementation only concentrates on property maps and doesn't use the interface I currently envision).