Jump to content
  • Advertisement
SR D

C++ How to memcpy std::map values to a pointer?

Recommended Posts

Posted (edited)

I have a std::map<int, Point> keyed by the points id. I need to do the equivalent of a memcpy into a pointer like the following.

struct Point {
    float x, y, z;
    float nx, ny, nz;
};

// ...

std::map<int, Point> meshA = submesh.at(2);

Point* points = reinterpret_cast<Point*>(OGRE_MALLOC_SIMD(sizeof(Point) * totalPoints(), Ogre::MEMCATEGORY_GEOMETRY));

// memcpy into points?
  

After allocating the memory, how does one do the equivalent of a memcpy of std::map<int, Point> into 'Point* points'? I have to populate this pointer (Point *) which is the type my engine API takes.

Edited by SR D

Share this post


Link to post
Share on other sites
Advertisement
Posted (edited)

Do you just want the 'Point' instances from the map, without the IDs? [Edit: I'm guessing that's the case based on the use of 'Point *', but it might still be worth clarifying that.] And does order matter? (E.g. do you want the points ordered by ascending ID?)

Edited by Zakwayda

Share this post


Link to post
Share on other sites
Posted (edited)

Yeah, I should have clarified that.

No, the point id's wouldn't be a part of it. Just the point structures. Yes, order does matter.

Edited by SR D

Share this post


Link to post
Share on other sites

Assuming the order you want is by ascending ID, then I think you'll need to iterate over the map and process each 'Point' instance one at a time (either implicitly or explicitly - there are various ways you could express it using standard library features).

There may be other issues involved, such as padding, alignment, reinterpret_cast vs static_cast, and so on, but I don't know much about the context you're working in, so I won't comment on those issues. It sounds like the key question though is how to extract the 'Point' instances from the map, and I think the answer is that, one way or another, it needs to be done one at a time.

Share this post


Link to post
Share on other sites

I think you need to question why you have an std::map<> from int to Point in the first place... but assuming it's working fine for you, what's wrong with...

void populate_raw_array(Point * &dest, int & maxN, std::map<int,Point> source const) {
  if( maxN > source.size() ) maxN = source.size();
  for (auto dp = dest, i = source.begin(), n = maxN; n != 0; ++dp, ++i, --n) {
    *dp = i->second;
  }
}

// Usage...
Point buffer[256];
int size = 256;
populate_raw_array(buffer, size, my_map_of_points);
// buffer[0] through buffer[size], exclusive, now have points in.

 

Share this post


Link to post
Share on other sites

You could way more simple store all your points in memory and have the map just point to an Integer to Point-Pointer pair instead of to just the Point instance itself

Share this post


Link to post
Share on other sites

Using SIMD implies you need the points in contiguous memory, which a map does not have.

You could use std::transform() from the map to the SIMD memory using a simple lambda to get the second member of the map pair.

transform(begin(meshA), end(meshA),
          back_inserter(points),
          [](map<int,Point>::value_type const& mp) -> Point
              { return mp.second; });

You could also use a loop.

auto p = points;
for (auto const& mp: meshA)
    *p++ = mp.second;

There is no more efficient way.

Note that std::map is a sorted associative container, so no fancy sorting is necessary, unless your desired sort order differs from the one you're sorting the map by.  In that case, std::sort is your best friend, but you might also consider why you're using a sorted associative container in the first place if you're not using the sort order of the container.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!