Search Results

Search found 3 results on 1 pages for 'cuppm'.

Page 1/1 | 1 

  • Boost::Interprocess Container Container Resizing No Default Constructor

    - by CuppM
    Hi, After combing through the Boost::Interprocess documentation and Google searches, I think I've found the reason/workaround to my issue. Everything I've found, as I understand it, seems to be hinting at this, but doesn't come out and say "do this because...". But if anyone can verify this I would appreciate it. I'm writing a series of classes that represent a large lookup of information that is stored in memory for fast performance in a parallelized application. Because of the size of data and multiple processes that run at a time on one machine, we're using Boost::Interprocess for shared memory to have a single copy of the structures. I looked at the Boost::Interprocess documentation and examples, and they typedef classes for shared memory strings, string vectors, int vector vectors, etc. And when they "use" them in their examples, they just construct them passing the allocator and maybe insert one item that they've constructed elsewhere. Like on this page: http://www.boost.org/doc/libs/1_42_0/doc/html/interprocess/allocators_containers.html So following their examples, I created a header file with typedefs for shared memory classes: namespace shm { namespace bip = boost::interprocess; // General/Utility Types typedef bip::managed_shared_memory::segment_manager segment_manager_t; typedef bip::allocator<void, segment_manager_t> void_allocator; // Integer Types typedef bip::allocator<int, segment_manager_t> int_allocator; typedef bip::vector<int, int_allocator> int_vector; // String Types typedef bip::allocator<char, segment_manager_t> char_allocator; typedef bip::basic_string<char, std::char_traits<char>, char_allocator> string; typedef bip::allocator<string, segment_manager_t> string_allocator; typedef bip::vector<string, string_allocator> string_vector; typedef bip::allocator<string_vector, segment_manager_t> string_vector_allocator; typedef bip::vector<string_vector, string_vector_allocator> string_vector_vector; } Then for one of my lookup table classes, it's defined something like this: class Details { public: Details(const shm::void_allocator & alloc) : m_Ids(alloc), m_Labels(alloc), m_Values(alloc) { } ~Details() {} int Read(BinaryReader & br); private: shm::int_vector m_Ids; shm::string_vector m_Labels; shm::string_vector_vector m_Values; }; int Details::Read(BinaryReader & br) { int num = br.ReadInt(); m_Ids.resize(num); m_Labels.resize(num); m_Values.resize(num); for (int i = 0; i < num; i++) { m_Ids[i] = br.ReadInt(); m_Labels[i] = br.ReadString().c_str(); int count = br.ReadInt(); m_Value[i].resize(count); for (int j = 0; j < count; j++) { m_Value[i][j] = br.ReadString().c_str(); } } } But when I compile it, I get the error: 'boost::interprocess::allocator<T,SegmentManager>::allocator' : no appropriate default constructor available And it's due to the resize() calls on the vector objects. Because the allocator types do not have a empty constructor (they take a const segment_manager_t &) and it's trying to create a default object for each location. So in order for it to work, I have to get an allocator object and pass a default value object on resize. Like this: int Details::Read(BinaryReader & br) { shm::void_allocator alloc(m_Ids.get_allocator()); int num = br.ReadInt(); m_Ids.resize(num); m_Labels.resize(num, shm::string(alloc)); m_Values.resize(num, shm::string_vector(alloc)); for (int i = 0; i < num; i++) { m_Ids[i] = br.ReadInt(); m_Labels[i] = br.ReadString().c_str(); int count = br.ReadInt(); m_Value[i].resize(count, shm::string(alloc)); for (int j = 0; j < count; j++) { m_Value[i][j] = br.ReadString().c_str(); } } } Is this the best/correct way of doing it? Or am I missing something. Thanks!

    Read the article

  • Boost::Container::Vector with Enum Template Argument - Not Legal Base Class

    - by CuppM
    Hi, I'm using Visual Studio 2008 with the Boost v1.42.0 library. If I use an enum as the template argument, I get a compile error when adding a value using push_back(). The compiler error is: 'T': is not a legal base class and the location of the error is move.hpp line 79. #include <boost/interprocess/containers/vector.hpp> class Test { public: enum Types { Unknown = 0, First = 1, Second = 2, Third = 3 }; typedef boost::container::vector<Types> TypesVector; }; int main() { Test::TypesVector o; o.push_back(Test::First); return 0; } If I use a std::vector instead it works. And if I resize the Boost version first and then set the values using the [] operator it also works. Is there some way to make this work using push_back()?

    Read the article

  • SQL Server - Get Inserted Record Identity Value when Using a View's Instead Of Trigger

    - by CuppM
    For several tables that have identity fields, we are implementing a Row Level Security scheme using Views and Instead Of triggers on those views. Here is a simplified example structure: -- Table CREATE TABLE tblItem ( ItemId int identity(1,1) primary key, Name varchar(20) ) go -- View CREATE VIEW vwItem AS SELECT * FROM tblItem -- RLS Filtering Condition go -- Instead Of Insert Trigger CREATE TRIGGER IO_vwItem_Insert ON vwItem INSTEAD OF INSERT AS BEGIN -- RLS Security Checks on inserted Table -- Insert Records Into Table INSERT INTO tblItem (Name) SELECT Name FROM inserted; END go If I want to insert a record and get its identity, before implementing the RLS Instead Of trigger, I used: DECLARE @ItemId int; INSERT INTO tblItem (Name) VALUES ('MyName'); SELECT @ItemId = SCOPE_IDENTITY(); With the trigger, SCOPE_IDENTITY() no longer works - it returns NULL. I've seen suggestions for using the OUTPUT clause to get the identity back, but I can't seem to get it to work the way I need it to. If I put the OUTPUT clause on the view insert, nothing is ever entered into it. -- Nothing is added to @ItemIds DECLARE @ItemIds TABLE (ItemId int); INSERT INTO vwItem (Name) OUTPUT INSERTED.ItemId INTO @ItemIds VALUES ('MyName'); If I put the OUTPUT clause in the trigger on the INSERT statement, the trigger returns the table (I can view it from SQL Management Studio). I can't seem to capture it in the calling code; either by using an OUTPUT clause on that call or using a SELECT * FROM (). -- Modified Instead Of Insert Trigger w/ Output CREATE TRIGGER IO_vwItem_Insert ON vwItem INSTEAD OF INSERT AS BEGIN -- RLS Security Checks on inserted Table -- Insert Records Into Table INSERT INTO tblItem (Name) OUTPUT INSERTED.ItemId SELECT Name FROM inserted; END go -- Calling Code INSERT INTO vwItem (Name) VALUES ('MyName'); The only thing I can think of is to use the IDENT_CURRENT() function. Since that doesn't operate in the current scope, there's an issue of concurrent users inserting at the same time and messing it up. If the entire operation is wrapped in a transaction, would that prevent the concurrency issue? BEGIN TRANSACTION DECLARE @ItemId int; INSERT INTO tblItem (Name) VALUES ('MyName'); SELECT @ItemId = IDENT_CURRENT('tblItem'); COMMIT TRANSACTION Does anyone have any suggestions on how to do this better? I know people out there who will read this and say "Triggers are EVIL, don't use them!" While I appreciate your convictions, please don't offer that "suggestion".

    Read the article

1